summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 16:28:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 16:28:20 +0000
commitdcc721a95bef6f0d8e6d8775b8efe33e5aecd562 (patch)
tree66a2774cd0ee294d019efd71d2544c70f42b2842 /tests
parentInitial commit. (diff)
downloadrsyslog-dcc721a95bef6f0d8e6d8775b8efe33e5aecd562.tar.xz
rsyslog-dcc721a95bef6f0d8e6d8775b8efe33e5aecd562.zip
Adding upstream version 8.2402.0.upstream/8.2402.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/1.rstest26
-rw-r--r--tests/2.rstest10
-rw-r--r--tests/3.rstest21
-rw-r--r--tests/CI/centos6-9.supp32
-rw-r--r--tests/CI/centos7.supp9
-rw-r--r--tests/CI/gcov.supp6
-rw-r--r--tests/CI/ubuntu20.04.supp42
-rw-r--r--tests/DevNull.cfgtest2
-rw-r--r--tests/Makefile.am3148
-rw-r--r--tests/Makefile.in4452
-rw-r--r--tests/NoExistFile.cfgtest2
-rw-r--r--tests/README102
-rwxr-xr-xtests/abort-uncleancfg-badcfg-check.sh13
-rwxr-xr-xtests/abort-uncleancfg-badcfg-check_1.sh15
-rwxr-xr-xtests/abort-uncleancfg-goodcfg-check.sh13
-rwxr-xr-xtests/abort-uncleancfg-goodcfg.sh27
-rwxr-xr-xtests/action-tx-errfile-maxsize.sh35
-rwxr-xr-xtests/action-tx-errfile.sh40
-rwxr-xr-xtests/action-tx-single-processing.sh38
-rwxr-xr-xtests/allowed-sender-tcp-fail.sh26
-rwxr-xr-xtests/allowed-sender-tcp-hostname-fail.sh31
-rwxr-xr-xtests/allowed-sender-tcp-hostname-ok.sh23
-rwxr-xr-xtests/allowed-sender-tcp-ok.sh22
-rwxr-xr-xtests/array_lookup_table-vg.sh5
-rwxr-xr-xtests/array_lookup_table.sh53
-rwxr-xr-xtests/array_lookup_table_misuse-vg.sh45
-rwxr-xr-xtests/arrayqueue.sh21
-rwxr-xr-xtests/asynwr_deadlock.sh40
-rwxr-xr-xtests/asynwr_deadlock2.sh85
-rwxr-xr-xtests/asynwr_deadlock4.sh40
-rwxr-xr-xtests/asynwr_deadlock_2.sh32
-rwxr-xr-xtests/asynwr_dynfile_flushtxend-off.sh38
-rwxr-xr-xtests/asynwr_simple.sh26
-rwxr-xr-xtests/asynwr_simple_2.sh22
-rwxr-xr-xtests/asynwr_small.sh38
-rwxr-xr-xtests/asynwr_timeout.sh34
-rwxr-xr-xtests/asynwr_timeout_2.sh37
-rwxr-xr-xtests/asynwr_tinybuf.sh36
-rw-r--r--tests/bad_qi/dbq.qi29
-rwxr-xr-xtests/badqi.sh31
-rwxr-xr-xtests/cee_diskqueue.sh23
-rwxr-xr-xtests/cee_simple.sh23
-rwxr-xr-xtests/cfg.sh140
-rw-r--r--tests/cfg1.cfgtest3
-rw-r--r--tests/cfg1.testin2
-rw-r--r--tests/cfg2.cfgtest3
-rw-r--r--tests/cfg2.testin1
-rw-r--r--tests/cfg3.cfgtest5
-rw-r--r--tests/cfg3.testin1
-rw-r--r--tests/cfg4.cfgtest1
-rw-r--r--tests/cfg4.testin31
-rw-r--r--tests/check_relpEngineVersion.c66
-rw-r--r--tests/chkseq.c249
-rwxr-xr-xtests/clickhouse-basic-vg.sh3
-rwxr-xr-xtests/clickhouse-basic.sh30
-rwxr-xr-xtests/clickhouse-bulk-load-vg.sh3
-rwxr-xr-xtests/clickhouse-bulk-load.sh30
-rwxr-xr-xtests/clickhouse-bulk-vg.sh3
-rwxr-xr-xtests/clickhouse-bulk.sh39
-rwxr-xr-xtests/clickhouse-dflt-tpl.sh24
-rwxr-xr-xtests/clickhouse-errorfile.sh32
-rwxr-xr-xtests/clickhouse-limited-batch.sh31
-rwxr-xr-xtests/clickhouse-load-vg.sh3
-rwxr-xr-xtests/clickhouse-load.sh31
-rwxr-xr-xtests/clickhouse-retry-error.sh27
-rwxr-xr-xtests/clickhouse-select.sh28
-rwxr-xr-xtests/clickhouse-start.sh31
-rwxr-xr-xtests/clickhouse-stop.sh19
-rwxr-xr-xtests/clickhouse-wrong-insert-syntax.sh30
-rwxr-xr-xtests/clickhouse-wrong-quotation-marks.sh33
-rwxr-xr-xtests/clickhouse-wrong-template-option.sh31
-rwxr-xr-xtests/complex1.sh132
-rwxr-xr-xtests/compresssp-stringtpl.sh26
-rwxr-xr-xtests/compresssp.sh29
-rwxr-xr-xtests/config_enabled-off.sh18
-rwxr-xr-xtests/config_enabled-on.sh19
-rwxr-xr-xtests/config_multiple_include.sh32
-rwxr-xr-xtests/config_output-o-option.sh18
-rwxr-xr-xtests/da-mainmsg-q.sh49
-rwxr-xr-xtests/da-queue-persist.sh47
-rwxr-xr-xtests/daqueue-dirty-shutdown.sh116
-rwxr-xr-xtests/daqueue-invld-qi.sh51
-rwxr-xr-xtests/daqueue-persist-drvr.sh54
-rwxr-xr-xtests/daqueue-persist.sh19
-rwxr-xr-xtests/diag.sh2946
-rw-r--r--tests/diagtalker.c165
-rwxr-xr-xtests/dircreate_dflt.sh27
-rwxr-xr-xtests/dircreate_off.sh28
-rwxr-xr-xtests/discard-allmark-vg.sh35
-rwxr-xr-xtests/discard-allmark.sh25
-rwxr-xr-xtests/discard-rptdmsg-vg.sh4
-rwxr-xr-xtests/discard-rptdmsg.sh20
-rwxr-xr-xtests/discard.sh23
-rwxr-xr-xtests/diskq-rfc5424.sh42
-rwxr-xr-xtests/diskqueue-fail.sh35
-rwxr-xr-xtests/diskqueue-fsync.sh35
-rwxr-xr-xtests/diskqueue-full.sh32
-rwxr-xr-xtests/diskqueue-multithread-es.sh52
-rwxr-xr-xtests/diskqueue-non-unique-prefix.sh29
-rwxr-xr-xtests/diskqueue.sh31
-rwxr-xr-xtests/dnscache-TTL-0-vg.sh4
-rwxr-xr-xtests/dnscache-TTL-0.sh21
-rwxr-xr-xtests/dynfile_invalid2.sh42
-rwxr-xr-xtests/dynfile_invld_async.sh42
-rwxr-xr-xtests/dynfile_invld_sync.sh42
-rwxr-xr-xtests/dynstats-json-vg.sh41
-rwxr-xr-xtests/dynstats-json.sh40
-rwxr-xr-xtests/dynstats-vg.sh45
-rwxr-xr-xtests/dynstats.sh42
-rwxr-xr-xtests/dynstats_ctr_reset.sh51
-rwxr-xr-xtests/dynstats_nometric.sh44
-rwxr-xr-xtests/dynstats_overflow-vg.sh102
-rwxr-xr-xtests/dynstats_overflow.sh102
-rwxr-xr-xtests/dynstats_prevent_premature_eviction-vg.sh58
-rwxr-xr-xtests/dynstats_prevent_premature_eviction.sh53
-rwxr-xr-xtests/dynstats_reset-vg.sh57
-rwxr-xr-xtests/dynstats_reset.sh56
-rwxr-xr-xtests/dynstats_reset_without_pstats_reset.sh53
-rw-r--r--tests/elasticsearch-error-format-check.py137
-rwxr-xr-xtests/elasticsearch-stop.sh7
-rwxr-xr-xtests/empty-app-name.sh19
-rwxr-xr-xtests/empty-hostname.sh29
-rwxr-xr-xtests/empty-prop-comparison.sh25
-rwxr-xr-xtests/empty-ruleset.sh34
-rw-r--r--tests/err1.rstest7
-rwxr-xr-xtests/es-basic-bulk-vg.sh3
-rwxr-xr-xtests/es-basic-bulk.sh30
-rwxr-xr-xtests/es-basic-errfile-empty.sh34
-rwxr-xr-xtests/es-basic-errfile-popul.sh48
-rwxr-xr-xtests/es-basic-es6.0.sh29
-rwxr-xr-xtests/es-basic-es7.14.sh29
-rwxr-xr-xtests/es-basic-ha-vg.sh29
-rwxr-xr-xtests/es-basic-ha.sh34
-rwxr-xr-xtests/es-basic-server.sh27
-rwxr-xr-xtests/es-basic-vg.sh3
-rwxr-xr-xtests/es-basic-vgthread.sh32
-rwxr-xr-xtests/es-basic.sh73
-rwxr-xr-xtests/es-bulk-errfile-empty.sh37
-rwxr-xr-xtests/es-bulk-errfile-popul-def-format.sh52
-rwxr-xr-xtests/es-bulk-errfile-popul-def-interleaved.sh55
-rwxr-xr-xtests/es-bulk-errfile-popul-erronly-interleaved.sh56
-rwxr-xr-xtests/es-bulk-errfile-popul-erronly.sh55
-rwxr-xr-xtests/es-bulk-errfile-popul.sh45
-rwxr-xr-xtests/es-bulk-retry.sh298
-rwxr-xr-xtests/es-duplicated-ruleset-vg.sh6
-rwxr-xr-xtests/es-duplicated-ruleset.sh44
-rwxr-xr-xtests/es-execOnlyWhenPreviousSuspended.sh50
-rwxr-xr-xtests/es-maxbytes-bulk.sh30
-rwxr-xr-xtests/es-searchType-empty.sh35
-rwxr-xr-xtests/es-writeoperation.sh118
-rw-r--r--tests/es_response_get_msgnum.py8
-rwxr-xr-xtests/exec_tpl-concurrency.sh34
-rwxr-xr-xtests/execonlyonce.sh34
-rwxr-xr-xtests/execonlywhenprevsuspended-nonsusp-queue.sh40
-rwxr-xr-xtests/execonlywhenprevsuspended-nonsusp.sh36
-rwxr-xr-xtests/execonlywhenprevsuspended-queue.sh36
-rwxr-xr-xtests/execonlywhenprevsuspended.sh28
-rwxr-xr-xtests/execonlywhenprevsuspended2.sh36
-rwxr-xr-xtests/execonlywhenprevsuspended3.sh35
-rwxr-xr-xtests/execonlywhenprevsuspended4.sh31
-rwxr-xr-xtests/execonlywhenprevsuspended_multiwrkr.sh29
-rwxr-xr-xtests/externalstate-failed-rcvr.sh31
-rwxr-xr-xtests/fac_authpriv.sh22
-rwxr-xr-xtests/fac_ftp.sh19
-rwxr-xr-xtests/fac_invld1.sh21
-rwxr-xr-xtests/fac_invld2.sh21
-rwxr-xr-xtests/fac_invld3.sh21
-rwxr-xr-xtests/fac_invld4_rfc5424.sh21
-rwxr-xr-xtests/fac_local0-vg.sh4
-rwxr-xr-xtests/fac_local0.sh22
-rwxr-xr-xtests/fac_local7.sh21
-rwxr-xr-xtests/fac_mail.sh20
-rwxr-xr-xtests/fac_news.sh21
-rwxr-xr-xtests/fac_ntp.sh19
-rwxr-xr-xtests/fac_uucp.sh21
-rwxr-xr-xtests/failover-async.sh29
-rwxr-xr-xtests/failover-basic-vg.sh29
-rwxr-xr-xtests/failover-basic.sh21
-rwxr-xr-xtests/failover-double.sh20
-rwxr-xr-xtests/failover-no-basic-vg.sh37
-rwxr-xr-xtests/failover-no-basic.sh29
-rwxr-xr-xtests/failover-no-rptd-vg.sh26
-rwxr-xr-xtests/failover-no-rptd.sh29
-rwxr-xr-xtests/failover-rptd-vg.sh31
-rwxr-xr-xtests/failover-rptd.sh21
-rw-r--r--tests/faketime_common.sh60
-rwxr-xr-xtests/fieldtest-udp.sh29
-rwxr-xr-xtests/fieldtest.sh29
-rwxr-xr-xtests/func-substring-invld-startpos-vg.sh3
-rwxr-xr-xtests/func-substring-invld-startpos.sh17
-rwxr-xr-xtests/func-substring-large-endpos.sh17
-rwxr-xr-xtests/func-substring-large-neg-endpos.sh17
-rwxr-xr-xtests/func-substring-relative-endpos.sh17
-rwxr-xr-xtests/glbl-internalmsg_severity-debug-not_shown.sh16
-rwxr-xr-xtests/glbl-internalmsg_severity-debug-shown.sh17
-rwxr-xr-xtests/glbl-internalmsg_severity-info-shown.sh17
-rwxr-xr-xtests/glbl-invld-param.sh18
-rwxr-xr-xtests/glbl-oversizeMsg-log-vg.sh37
-rwxr-xr-xtests/glbl-oversizeMsg-log.sh37
-rwxr-xr-xtests/glbl-oversizeMsg-split.sh56
-rwxr-xr-xtests/glbl-oversizeMsg-truncate-imfile.sh47
-rwxr-xr-xtests/glbl-oversizeMsg-truncate.sh46
-rwxr-xr-xtests/glbl-ruleset-queue-defaults.sh21
-rwxr-xr-xtests/glbl-umask.sh29
-rwxr-xr-xtests/glbl-unloadmodules.sh27
-rwxr-xr-xtests/glbl_setenv.sh26
-rwxr-xr-xtests/glbl_setenv_2_vars.sh28
-rwxr-xr-xtests/glbl_setenv_err.sh25
-rwxr-xr-xtests/glbl_setenv_err_too_long.sh25
-rwxr-xr-xtests/global_vars.sh34
-rwxr-xr-xtests/gzipwr_flushInterval.sh28
-rwxr-xr-xtests/gzipwr_flushOnTXEnd.sh32
-rwxr-xr-xtests/gzipwr_hup-vg.sh4
-rwxr-xr-xtests/gzipwr_hup.sh35
-rwxr-xr-xtests/gzipwr_hup_multi_file.sh46
-rwxr-xr-xtests/gzipwr_hup_single_file.sh40
-rwxr-xr-xtests/gzipwr_large.sh35
-rwxr-xr-xtests/gzipwr_large_dynfile.sh52
-rwxr-xr-xtests/gzipwr_rscript.sh21
-rw-r--r--tests/have_relpEngineSetTLSLibByName.c10
-rw-r--r--tests/have_relpSrvSetOversizeMode.c10
-rw-r--r--tests/have_relpSrvSetTlsConfigCmd.c10
-rwxr-xr-xtests/hostname-with-slash-dflt-invld.sh28
-rwxr-xr-xtests/hostname-with-slash-dflt-slash-valid.sh26
-rwxr-xr-xtests/hostname-with-slash-pmrfc3164.sh25
-rwxr-xr-xtests/hostname-with-slash-pmrfc5424.sh25
-rwxr-xr-xtests/imbatchreport_delete_structdata.sh42
-rwxr-xr-xtests/imbatchreport_delete_success.sh48
-rwxr-xr-xtests/imbatchreport_delete_toolarge.sh48
-rwxr-xr-xtests/imbatchreport_errmsg_delete_params.sh16
-rwxr-xr-xtests/imbatchreport_errmsg_glob_dir_fake.sh16
-rwxr-xr-xtests/imbatchreport_errmsg_glob_dir_not_dir.sh15
-rwxr-xr-xtests/imbatchreport_errmsg_glob_not_regular.sh15
-rwxr-xr-xtests/imbatchreport_errmsg_no_params-vg.sh4
-rwxr-xr-xtests/imbatchreport_errmsg_no_params.sh17
-rwxr-xr-xtests/imbatchreport_errmsg_not_supported1.sh16
-rwxr-xr-xtests/imbatchreport_errmsg_not_supported2.sh16
-rwxr-xr-xtests/imbatchreport_errmsg_not_supported3.sh16
-rwxr-xr-xtests/imbatchreport_errmsg_regex.match.reject.sh16
-rwxr-xr-xtests/imbatchreport_errmsg_regex.match.rename.sh16
-rwxr-xr-xtests/imbatchreport_errmsg_regex.nomatch.sh16
-rwxr-xr-xtests/imbatchreport_errmsg_rename_params.sh16
-rwxr-xr-xtests/imbatchreport_rename_success.sh48
-rwxr-xr-xtests/imbatchreport_rename_toolarge.sh48
-rwxr-xr-xtests/imdocker-basic-vg.sh3
-rwxr-xr-xtests/imdocker-basic.sh37
-rwxr-xr-xtests/imdocker-long-logline-vg.sh6
-rwxr-xr-xtests/imdocker-long-logline.sh43
-rwxr-xr-xtests/imdocker-multi-line-vg.sh6
-rwxr-xr-xtests/imdocker-multi-line.sh47
-rwxr-xr-xtests/imdocker-new-logs-from-start-vg.sh3
-rwxr-xr-xtests/imdocker-new-logs-from-start.sh53
-rwxr-xr-xtests/imdtls-basic-timeout45
-rwxr-xr-xtests/imdtls-basic-tlscommands.sh46
-rwxr-xr-xtests/imdtls-basic-vg.sh9
-rwxr-xr-xtests/imdtls-basic.sh37
-rwxr-xr-xtests/imdtls-error-cert.sh28
-rwxr-xr-xtests/imdtls-sessionbreak-vg.sh9
-rwxr-xr-xtests/imdtls-sessionbreak.sh75
-rwxr-xr-xtests/imfile-basic-2GB-file.sh48
-rwxr-xr-xtests/imfile-basic-legacy.sh29
-rwxr-xr-xtests/imfile-basic-vg.sh3
-rwxr-xr-xtests/imfile-basic-vgthread.sh39
-rwxr-xr-xtests/imfile-basic.sh26
-rwxr-xr-xtests/imfile-discard-truncated-line.sh72
-rwxr-xr-xtests/imfile-endmsg.regex-vg.sh111
-rwxr-xr-xtests/imfile-endmsg.regex-with-example-vg.sh147
-rwxr-xr-xtests/imfile-endmsg.regex-with-example.sh157
-rw-r--r--tests/imfile-endmsg.regex.crio.rulebase15
-rw-r--r--tests/imfile-endmsg.regex.json.rulebase9
-rwxr-xr-xtests/imfile-endmsg.regex.sh110
-rwxr-xr-xtests/imfile-endregex-save-lf-persist.sh59
-rwxr-xr-xtests/imfile-endregex-save-lf.sh53
-rwxr-xr-xtests/imfile-endregex-timeout-none-polling.sh59
-rwxr-xr-xtests/imfile-endregex-timeout-none.sh54
-rwxr-xr-xtests/imfile-endregex-timeout-polling.sh61
-rwxr-xr-xtests/imfile-endregex-timeout-with-shutdown-polling.sh64
-rwxr-xr-xtests/imfile-endregex-timeout-with-shutdown.sh66
-rwxr-xr-xtests/imfile-endregex-timeout.sh46
-rwxr-xr-xtests/imfile-endregex-vg.sh73
-rwxr-xr-xtests/imfile-endregex.sh86
-rwxr-xr-xtests/imfile-error-not-repeated.sh51
-rwxr-xr-xtests/imfile-escapelf.replacement-empty.sh30
-rwxr-xr-xtests/imfile-escapelf.replacement.sh30
-rwxr-xr-xtests/imfile-file-not-found-error.sh45
-rwxr-xr-xtests/imfile-fileNotFoundError-parameter.sh26
-rwxr-xr-xtests/imfile-freshStartTail1.sh34
-rwxr-xr-xtests/imfile-freshStartTail2.sh29
-rwxr-xr-xtests/imfile-freshStartTail3.sh33
-rwxr-xr-xtests/imfile-growing-file-id.sh79
-rwxr-xr-xtests/imfile-ignore-old-file-1.sh37
-rwxr-xr-xtests/imfile-ignore-old-file-2.sh43
-rwxr-xr-xtests/imfile-ignore-old-file-3.sh34
-rwxr-xr-xtests/imfile-ignore-old-file-4.sh31
-rwxr-xr-xtests/imfile-ignore-old-file-5.sh47
-rwxr-xr-xtests/imfile-ignore-old-file-6.sh42
-rwxr-xr-xtests/imfile-ignore-old-file-7.sh56
-rwxr-xr-xtests/imfile-logrotate-async.sh108
-rwxr-xr-xtests/imfile-logrotate-copytruncate.sh79
-rwxr-xr-xtests/imfile-logrotate-multiple.sh85
-rwxr-xr-xtests/imfile-logrotate-nocopytruncate.sh78
-rwxr-xr-xtests/imfile-logrotate.sh77
-rwxr-xr-xtests/imfile-old-state-file.sh87
-rwxr-xr-xtests/imfile-persist-state-1.sh30
-rwxr-xr-xtests/imfile-readmode0-vg.sh63
-rwxr-xr-xtests/imfile-readmode2-polling.sh75
-rwxr-xr-xtests/imfile-readmode2-vg.sh72
-rwxr-xr-xtests/imfile-readmode2-with-persists-data-during-stop.sh102
-rwxr-xr-xtests/imfile-readmode2-with-persists.sh97
-rwxr-xr-xtests/imfile-readmode2.sh74
-rwxr-xr-xtests/imfile-rename-while-stopped.sh70
-rwxr-xr-xtests/imfile-rename.sh91
-rwxr-xr-xtests/imfile-statefile-delete.sh44
-rwxr-xr-xtests/imfile-statefile-directory.sh32
-rwxr-xr-xtests/imfile-statefile-no-delete.sh36
-rwxr-xr-xtests/imfile-statefile-no-file_id-TO-file_id.sh49
-rwxr-xr-xtests/imfile-statefile-no-file_id.sh45
-rwxr-xr-xtests/imfile-symlink-ext-tmp-dir-tree.sh80
-rwxr-xr-xtests/imfile-symlink-multi.sh70
-rwxr-xr-xtests/imfile-symlink.sh68
-rwxr-xr-xtests/imfile-truncate-2GB-file.sh48
-rwxr-xr-xtests/imfile-truncate-line.sh75
-rwxr-xr-xtests/imfile-truncate-multiple.sh52
-rwxr-xr-xtests/imfile-truncate.sh41
-rwxr-xr-xtests/imfile-wildcards-dirs-multi.sh91
-rwxr-xr-xtests/imfile-wildcards-dirs-multi2.sh91
-rwxr-xr-xtests/imfile-wildcards-dirs-multi3.sh96
-rwxr-xr-xtests/imfile-wildcards-dirs-multi4.sh95
-rwxr-xr-xtests/imfile-wildcards-dirs-multi5-polling.sh74
-rwxr-xr-xtests/imfile-wildcards-dirs-multi5.sh87
-rwxr-xr-xtests/imfile-wildcards-dirs.sh70
-rwxr-xr-xtests/imfile-wildcards-dirs2.sh91
-rwxr-xr-xtests/imfile-wildcards.sh92
-rwxr-xr-xtests/imhiredis-queue-lpop-vg.sh7
-rwxr-xr-xtests/imhiredis-queue-lpop.sh52
-rwxr-xr-xtests/imhiredis-queue-vg.sh7
-rwxr-xr-xtests/imhiredis-queue.sh51
-rwxr-xr-xtests/imhiredis-redis-restart-vg.sh7
-rwxr-xr-xtests/imhiredis-redis-restart.sh69
-rwxr-xr-xtests/imhiredis-redis-start-after-vg.sh7
-rwxr-xr-xtests/imhiredis-redis-start-after.sh55
-rwxr-xr-xtests/imhiredis-stream-consumerGroup-ack-vg.sh7
-rwxr-xr-xtests/imhiredis-stream-consumerGroup-ack.sh67
-rwxr-xr-xtests/imhiredis-stream-consumerGroup-noack-vg.sh7
-rwxr-xr-xtests/imhiredis-stream-consumerGroup-noack.sh68
-rwxr-xr-xtests/imhiredis-stream-consumerGroup-reclaim-vg.sh7
-rwxr-xr-xtests/imhiredis-stream-consumerGroup-reclaim.sh83
-rwxr-xr-xtests/imhiredis-stream-from-beginning-vg.sh7
-rwxr-xr-xtests/imhiredis-stream-from-beginning.sh60
-rwxr-xr-xtests/imhiredis-stream-vg.sh7
-rwxr-xr-xtests/imhiredis-stream.sh60
-rwxr-xr-xtests/imhiredis-subscribe-vg.sh7
-rwxr-xr-xtests/imhiredis-subscribe.sh60
-rwxr-xr-xtests/imhttp-getrequest-file-vg.sh4
-rwxr-xr-xtests/imhttp-getrequest-file.sh18
-rwxr-xr-xtests/imhttp-post-payload-basic-auth-vg.sh4
-rwxr-xr-xtests/imhttp-post-payload-basic-auth.sh62
-rwxr-xr-xtests/imhttp-post-payload-compress-vg.sh4
-rwxr-xr-xtests/imhttp-post-payload-compress.sh30
-rwxr-xr-xtests/imhttp-post-payload-large-vg.sh4
-rwxr-xr-xtests/imhttp-post-payload-large.sh52
-rwxr-xr-xtests/imhttp-post-payload-multi-lf-vg.sh4
-rwxr-xr-xtests/imhttp-post-payload-multi-lf.sh29
-rwxr-xr-xtests/imhttp-post-payload-multi-vg.sh4
-rwxr-xr-xtests/imhttp-post-payload-multi.sh27
-rwxr-xr-xtests/imhttp-post-payload-query-params-vg.sh4
-rwxr-xr-xtests/imhttp-post-payload-query-params.sh48
-rwxr-xr-xtests/imhttp-post-payload-vg.sh4
-rwxr-xr-xtests/imhttp-post-payload.sh38
-rwxr-xr-xtests/imjournal-basic-vg.sh3
-rwxr-xr-xtests/imjournal-basic.sh47
-rwxr-xr-xtests/imjournal-statefile-vg.sh3
-rwxr-xr-xtests/imjournal-statefile.sh69
-rwxr-xr-xtests/imkafka-backgrounded.sh61
-rwxr-xr-xtests/imkafka-config-err-param.sh57
-rwxr-xr-xtests/imkafka-config-err-ruleset.sh58
-rwxr-xr-xtests/imkafka-hang-on-no-kafka.sh35
-rwxr-xr-xtests/imkafka-hang-other-action-on-no-kafka.sh39
-rwxr-xr-xtests/imkafka-vg.sh3
-rwxr-xr-xtests/imkafka.sh57
-rwxr-xr-xtests/imkafka_multi_group.sh112
-rwxr-xr-xtests/imkafka_multi_single.sh151
-rwxr-xr-xtests/imklog_permitnonkernelfacility_root.sh32
-rwxr-xr-xtests/immark-inputname.sh18
-rwxr-xr-xtests/immark-ruleset-custom-msg.sh22
-rwxr-xr-xtests/immark-ruleset.sh22
-rwxr-xr-xtests/immark.sh19
-rwxr-xr-xtests/improg-multiline-test.py6
-rwxr-xr-xtests/improg-simul.sh70
-rwxr-xr-xtests/improg_errmsg_no_params-vg.sh4
-rwxr-xr-xtests/improg_errmsg_no_params.sh17
-rwxr-xr-xtests/improg_prog_confirm.sh27
-rwxr-xr-xtests/improg_prog_confirm_killonclose.sh28
-rwxr-xr-xtests/improg_prog_killonclose.sh25
-rwxr-xr-xtests/improg_prog_simple-vg.sh4
-rwxr-xr-xtests/improg_prog_simple.sh24
-rwxr-xr-xtests/improg_simple_multi.sh23
-rwxr-xr-xtests/impstats-hup.sh26
-rwxr-xr-xtests/imptcp-NUL-rawmsg.sh27
-rwxr-xr-xtests/imptcp-NUL.sh21
-rwxr-xr-xtests/imptcp-basic-hup.sh22
-rwxr-xr-xtests/imptcp-connection-msg-disabled.sh39
-rwxr-xr-xtests/imptcp-connection-msg-received.sh40
-rwxr-xr-xtests/imptcp-discard-truncated-msg.sh32
-rwxr-xr-xtests/imptcp-maxFrameSize-parameter.sh28
-rwxr-xr-xtests/imptcp-msg-truncation-on-number.sh38
-rwxr-xr-xtests/imptcp-msg-truncation-on-number2.sh46
-rwxr-xr-xtests/imptcp-octet-framing-too-long-vg.sh23
-rwxr-xr-xtests/imptcp-oversize-message-display.sh43
-rwxr-xr-xtests/imptcp_addtlframedelim.sh22
-rwxr-xr-xtests/imptcp_conndrop-vg.sh6
-rwxr-xr-xtests/imptcp_conndrop.sh30
-rwxr-xr-xtests/imptcp_framing_regex-oversize.sh45
-rwxr-xr-xtests/imptcp_framing_regex.sh39
-rwxr-xr-xtests/imptcp_large.sh27
-rwxr-xr-xtests/imptcp_maxsessions.sh47
-rwxr-xr-xtests/imptcp_multi_line.sh27
-rwxr-xr-xtests/imptcp_no_octet_counted.sh21
-rwxr-xr-xtests/imptcp_nonProcessingPoller.sh25
-rwxr-xr-xtests/imptcp_spframingfix.sh21
-rwxr-xr-xtests/imptcp_veryLargeOctateCountedMessages.sh26
-rwxr-xr-xtests/imrelp-basic-hup.sh21
-rwxr-xr-xtests/imrelp-basic-oldstyle.sh19
-rwxr-xr-xtests/imrelp-basic-vg.sh3
-rwxr-xr-xtests/imrelp-basic.sh19
-rwxr-xr-xtests/imrelp-bigmessage.sh79
-rwxr-xr-xtests/imrelp-invld-tlslib.sh16
-rwxr-xr-xtests/imrelp-long-msg.sh19
-rwxr-xr-xtests/imrelp-manyconn-vg.sh9
-rwxr-xr-xtests/imrelp-manyconn.sh21
-rwxr-xr-xtests/imrelp-maxDataSize-error.sh31
-rwxr-xr-xtests/imrelp-oversizeMode-accept.sh33
-rwxr-xr-xtests/imrelp-oversizeMode-truncate.sh36
-rwxr-xr-xtests/imrelp-sessionbreak-vg.sh74
-rwxr-xr-xtests/imrelp-tls-cfgcmd.sh57
-rwxr-xr-xtests/imrelp-tls-chainedcert.sh47
-rwxr-xr-xtests/imrelp-tls-mixed-chainedcert.sh54
-rwxr-xr-xtests/imrelp-tls-mixed-chainedcert2.sh54
-rwxr-xr-xtests/imrelp-tls.sh36
-rwxr-xr-xtests/imtcp-NUL-rawmsg.sh27
-rwxr-xr-xtests/imtcp-NUL.sh21
-rwxr-xr-xtests/imtcp-basic-hup.sh22
-rwxr-xr-xtests/imtcp-basic.sh20
-rwxr-xr-xtests/imtcp-bigmessage-octetcounting.sh65
-rwxr-xr-xtests/imtcp-bigmessage-octetstuffing.sh65
-rwxr-xr-xtests/imtcp-connection-msg-recieved.sh24
-rwxr-xr-xtests/imtcp-discard-truncated-msg.sh26
-rwxr-xr-xtests/imtcp-drvr-in-input-basic.sh28
-rwxr-xr-xtests/imtcp-listen-port-file-2.sh38
-rwxr-xr-xtests/imtcp-maxFrameSize.sh27
-rwxr-xr-xtests/imtcp-msg-truncation-on-number.sh37
-rwxr-xr-xtests/imtcp-msg-truncation-on-number2.sh44
-rwxr-xr-xtests/imtcp-multi-drvr-basic-parallel.sh38
-rwxr-xr-xtests/imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh45
-rwxr-xr-xtests/imtcp-multi-drvr-basic.sh34
-rwxr-xr-xtests/imtcp-multiport.sh29
-rwxr-xr-xtests/imtcp-octet-framing-too-long-vg.sh23
-rwxr-xr-xtests/imtcp-tls-basic-verifydepth.sh30
-rwxr-xr-xtests/imtcp-tls-basic-vg.sh3
-rwxr-xr-xtests/imtcp-tls-basic.sh32
-rwxr-xr-xtests/imtcp-tls-gtls-x509fingerprint-invld.sh31
-rwxr-xr-xtests/imtcp-tls-gtls-x509fingerprint.sh34
-rwxr-xr-xtests/imtcp-tls-gtls-x509name-invld.sh28
-rwxr-xr-xtests/imtcp-tls-gtls-x509name-legacy.sh35
-rwxr-xr-xtests/imtcp-tls-gtls-x509name.sh32
-rwxr-xr-xtests/imtcp-tls-input-2certs.sh36
-rwxr-xr-xtests/imtcp-tls-input-basic.sh28
-rwxr-xr-xtests/imtcp-tls-no-lstn-startup.sh26
-rwxr-xr-xtests/imtcp-tls-ossl-basic-brokenhandshake-vg.sh40
-rwxr-xr-xtests/imtcp-tls-ossl-basic-tlscommands.sh53
-rwxr-xr-xtests/imtcp-tls-ossl-basic-verifydepth.sh30
-rwxr-xr-xtests/imtcp-tls-ossl-basic-vg.sh9
-rwxr-xr-xtests/imtcp-tls-ossl-basic.sh33
-rwxr-xr-xtests/imtcp-tls-ossl-error-ca.sh23
-rwxr-xr-xtests/imtcp-tls-ossl-error-cert.sh24
-rwxr-xr-xtests/imtcp-tls-ossl-error-key.sh24
-rwxr-xr-xtests/imtcp-tls-ossl-error-key2.sh23
-rwxr-xr-xtests/imtcp-tls-ossl-input-2certs.sh36
-rwxr-xr-xtests/imtcp-tls-ossl-input-basic.sh33
-rwxr-xr-xtests/imtcp-tls-ossl-invalid-verifydepth.sh20
-rwxr-xr-xtests/imtcp-tls-ossl-x509fingerprint.sh34
-rwxr-xr-xtests/imtcp-tls-ossl-x509name.sh34
-rwxr-xr-xtests/imtcp-tls-ossl-x509valid.sh33
-rwxr-xr-xtests/imtcp_addtlframedelim.sh21
-rwxr-xr-xtests/imtcp_addtlframedelim_on_input.sh21
-rwxr-xr-xtests/imtcp_conndrop.sh30
-rwxr-xr-xtests/imtcp_conndrop_tls-vg.sh6
-rwxr-xr-xtests/imtcp_conndrop_tls.sh34
-rwxr-xr-xtests/imtcp_incomplete_frame_at_end.sh27
-rwxr-xr-xtests/imtcp_no_octet_counted.sh21
-rwxr-xr-xtests/imtcp_spframingfix.sh21
-rwxr-xr-xtests/imtuxedoulog_data.sh40
-rwxr-xr-xtests/imtuxedoulog_errmsg_no_params-vg.sh4
-rwxr-xr-xtests/imtuxedoulog_errmsg_no_params.sh17
-rwxr-xr-xtests/imudp_thread_hang.sh20
-rwxr-xr-xtests/imuxsock_ccmiddle.sh28
-rwxr-xr-xtests/imuxsock_ccmiddle_root.sh32
-rwxr-xr-xtests/imuxsock_ccmiddle_syssock.sh35
-rwxr-xr-xtests/imuxsock_hostname.sh32
-rwxr-xr-xtests/imuxsock_legacy.sh23
-rwxr-xr-xtests/imuxsock_logger.sh20
-rwxr-xr-xtests/imuxsock_logger_err.sh29
-rwxr-xr-xtests/imuxsock_logger_parserchain.sh26
-rwxr-xr-xtests/imuxsock_logger_ratelimit.sh47
-rwxr-xr-xtests/imuxsock_logger_root.sh29
-rwxr-xr-xtests/imuxsock_logger_ruleset.sh28
-rwxr-xr-xtests/imuxsock_logger_ruleset_ratelimit.sh35
-rwxr-xr-xtests/imuxsock_logger_syssock.sh24
-rwxr-xr-xtests/imuxsock_traillf.sh25
-rwxr-xr-xtests/imuxsock_traillf_root.sh35
-rwxr-xr-xtests/imuxsock_traillf_syssock.sh27
-rwxr-xr-xtests/incltest.sh12
-rwxr-xr-xtests/incltest_dir.sh24
-rwxr-xr-xtests/incltest_dir_empty_wildcard.sh17
-rwxr-xr-xtests/incltest_dir_wildcard.sh12
-rwxr-xr-xtests/include-obj-in-if-vg.sh19
-rwxr-xr-xtests/include-obj-outside-control-flow-vg.sh23
-rwxr-xr-xtests/include-obj-text-from-file-noexist.sh15
-rwxr-xr-xtests/include-obj-text-from-file.sh18
-rwxr-xr-xtests/include-obj-text-vg.sh21
-rw-r--r--tests/inputfilegen.c234
-rwxr-xr-xtests/inputname-imtcp.sh32
-rwxr-xr-xtests/internal-errmsg-memleak-vg.sh37
-rwxr-xr-xtests/invalid_nested_include.sh28
-rw-r--r--tests/journal_print.c68
-rwxr-xr-xtests/json-nonstring.sh36
-rwxr-xr-xtests/json-onempty-at-end.sh23
-rwxr-xr-xtests/json_array_looping-vg.sh61
-rwxr-xr-xtests/json_array_looping.sh52
-rwxr-xr-xtests/json_array_subscripting.sh28
-rwxr-xr-xtests/json_nonarray_looping.sh42
-rwxr-xr-xtests/json_null-vg.sh38
-rwxr-xr-xtests/json_null.sh31
-rwxr-xr-xtests/json_null_array-vg.sh35
-rwxr-xr-xtests/json_null_array.sh28
-rwxr-xr-xtests/json_object_looping-vg.sh71
-rwxr-xr-xtests/json_object_looping.sh63
-rwxr-xr-xtests/json_object_suicide_in_loop-vg.sh53
-rwxr-xr-xtests/json_var_case.sh32
-rwxr-xr-xtests/json_var_cmpr.sh38
-rwxr-xr-xtests/kafka-selftest.sh60
-rwxr-xr-xtests/key_dereference_on_uninitialized_variable_space.sh31
-rwxr-xr-xtests/killrsyslog.sh16
-rw-r--r--tests/known_issues.supp62
-rwxr-xr-xtests/libdbi-asyn.sh30
-rwxr-xr-xtests/libdbi-basic-vg.sh6
-rwxr-xr-xtests/libdbi-basic.sh23
-rw-r--r--tests/libmaxmindb.supp57
-rwxr-xr-xtests/linkedlistqueue.sh22
-rw-r--r--tests/linux_localtime_r.supp126
-rwxr-xr-xtests/loadbalance.sh44
-rwxr-xr-xtests/localvar-concurrency.sh39
-rwxr-xr-xtests/lookup_table-hup-backgrounded.sh51
-rwxr-xr-xtests/lookup_table-vg.sh5
-rwxr-xr-xtests/lookup_table.sh49
-rwxr-xr-xtests/lookup_table_bad_configs-vg.sh5
-rwxr-xr-xtests/lookup_table_bad_configs.sh160
-rwxr-xr-xtests/lookup_table_no_hup_reload-vg.sh5
-rwxr-xr-xtests/lookup_table_no_hup_reload.sh34
-rwxr-xr-xtests/lookup_table_rscript_reload-vg.sh5
-rwxr-xr-xtests/lookup_table_rscript_reload.sh53
-rwxr-xr-xtests/lookup_table_rscript_reload_without_stub-vg.sh5
-rwxr-xr-xtests/lookup_table_rscript_reload_without_stub.sh51
-rwxr-xr-xtests/mainq_actq_DA.sh24
-rw-r--r--tests/mangle_qi.c113
-rwxr-xr-xtests/mangle_qi_usage_output.sh14
-rwxr-xr-xtests/manyptcp.sh22
-rwxr-xr-xtests/manytcp-too-few-tls-vg.sh42
-rwxr-xr-xtests/manytcp.sh27
-rw-r--r--tests/miniamqpsrvr.c658
-rwxr-xr-xtests/minitcpsrv_usage_output.sh14
-rw-r--r--tests/minitcpsrvr.c131
-rwxr-xr-xtests/mmanon_both_modes_compatible.sh31
-rwxr-xr-xtests/mmanon_ipv6_port.sh46
-rwxr-xr-xtests/mmanon_random_128_ipv6.sh65
-rwxr-xr-xtests/mmanon_random_32_ipv4.sh65
-rwxr-xr-xtests/mmanon_random_cons_128_ipembedded.sh82
-rwxr-xr-xtests/mmanon_random_cons_128_ipv6.sh82
-rwxr-xr-xtests/mmanon_random_cons_32_ipv4.sh92
-rwxr-xr-xtests/mmanon_recognize_ipembedded.sh63
-rwxr-xr-xtests/mmanon_recognize_ipv4.sh79
-rwxr-xr-xtests/mmanon_recognize_ipv6.sh55
-rwxr-xr-xtests/mmanon_simple_12_ipv4.sh44
-rwxr-xr-xtests/mmanon_simple_33_ipv4.sh84
-rwxr-xr-xtests/mmanon_simple_8_ipv4.sh31
-rwxr-xr-xtests/mmanon_simple_mallformed_ipv4.sh37
-rwxr-xr-xtests/mmanon_with_debug.sh82
-rwxr-xr-xtests/mmanon_zero_128_ipv6.sh46
-rwxr-xr-xtests/mmanon_zero_12_ipv4.sh31
-rwxr-xr-xtests/mmanon_zero_33_ipv4.sh42
-rwxr-xr-xtests/mmanon_zero_50_ipv6.sh38
-rwxr-xr-xtests/mmanon_zero_64_ipv6.sh37
-rwxr-xr-xtests/mmanon_zero_8_ipv4.sh31
-rwxr-xr-xtests/mmanon_zero_96_ipv6.sh38
-rwxr-xr-xtests/mmdarwin_errmsg_no_params.sh16
-rwxr-xr-xtests/mmdarwin_errmsg_no_sock-vg.sh4
-rwxr-xr-xtests/mmdarwin_errmsg_no_sock.sh16
-rwxr-xr-xtests/mmdb-container-empty.sh23
-rwxr-xr-xtests/mmdb-container.sh23
-rwxr-xr-xtests/mmdb-multilevel-vg.sh30
-rwxr-xr-xtests/mmdb-space.sh29
-rwxr-xr-xtests/mmdb-vg.sh27
-rw-r--r--tests/mmdb.rb3
-rwxr-xr-xtests/mmdb.sh29
-rwxr-xr-xtests/mmexternal-InvldProg-vg.sh33
-rwxr-xr-xtests/mmexternal-SegFault-empty-jroot-vg.sh23
-rwxr-xr-xtests/mmexternal-SegFault.sh25
-rwxr-xr-xtests/mmjsonparse-invalid-containerName.sh32
-rwxr-xr-xtests/mmjsonparse-w-o-cookie-multi-spaces.sh25
-rwxr-xr-xtests/mmjsonparse-w-o-cookie.sh25
-rwxr-xr-xtests/mmjsonparse_cim.sh26
-rwxr-xr-xtests/mmjsonparse_cim2.sh25
-rwxr-xr-xtests/mmjsonparse_extra_data-vg.sh31
-rwxr-xr-xtests/mmjsonparse_localvar.sh25
-rwxr-xr-xtests/mmjsonparse_simple.sh26
-rwxr-xr-xtests/mmkubernetes-basic-vg.sh187
-rw-r--r--tests/mmkubernetes-basic.out.json376
-rwxr-xr-xtests/mmkubernetes-basic.sh187
-rwxr-xr-xtests/mmkubernetes-cache-expire-vg.sh12
-rw-r--r--tests/mmkubernetes-cache-expire.out.expected109
-rwxr-xr-xtests/mmkubernetes-cache-expire.sh167
-rw-r--r--tests/mmkubernetes.supp16
-rw-r--r--tests/mmkubernetes_test_server.py165
-rwxr-xr-xtests/mmnormalize_parsesuccess-vg.sh4
-rwxr-xr-xtests/mmnormalize_parsesuccess.sh27
-rwxr-xr-xtests/mmnormalize_processing_test1.sh70
-rwxr-xr-xtests/mmnormalize_processing_test2.sh70
-rwxr-xr-xtests/mmnormalize_processing_test3.sh70
-rwxr-xr-xtests/mmnormalize_processing_test4.sh39
-rwxr-xr-xtests/mmnormalize_regex.sh28
-rwxr-xr-xtests/mmnormalize_regex_defaulted.sh28
-rwxr-xr-xtests/mmnormalize_regex_disabled.sh28
-rwxr-xr-xtests/mmnormalize_rule_from_array.sh33
-rwxr-xr-xtests/mmnormalize_rule_from_string.sh33
-rwxr-xr-xtests/mmnormalize_tokenized.sh46
-rwxr-xr-xtests/mmnormalize_variable.sh31
-rwxr-xr-xtests/mmpstrucdata-case.sh26
-rwxr-xr-xtests/mmpstrucdata-escaping.sh21
-rwxr-xr-xtests/mmpstrucdata-invalid-vg.sh33
-rwxr-xr-xtests/mmpstrucdata-vg.sh34
-rwxr-xr-xtests/mmpstrucdata.sh23
-rwxr-xr-xtests/mmrm1stspace-basic.sh32
-rwxr-xr-xtests/mmtaghostname_server.sh28
-rwxr-xr-xtests/mmtaghostname_tag.sh27
-rwxr-xr-xtests/mmutf8fix_no_error.sh96
-rwxr-xr-xtests/msg-deadlock-headerless-noappname.sh20
-rwxr-xr-xtests/msgdup.sh32
-rwxr-xr-xtests/msgdup_props.sh64
-rwxr-xr-xtests/msgvar-concurrency-array-event.tags.sh34
-rwxr-xr-xtests/msgvar-concurrency-array.sh34
-rwxr-xr-xtests/msgvar-concurrency.sh35
-rw-r--r--tests/msleep.c58
-rwxr-xr-xtests/msleep_usage_output.sh14
-rwxr-xr-xtests/multiple_lookup_tables-vg.sh5
-rwxr-xr-xtests/multiple_lookup_tables.sh46
-rwxr-xr-xtests/mysql-actq-mt-withpause-vg.sh4
-rwxr-xr-xtests/mysql-actq-mt-withpause.sh37
-rwxr-xr-xtests/mysql-actq-mt.sh30
-rwxr-xr-xtests/mysql-asyn-vg.sh4
-rwxr-xr-xtests/mysql-asyn.sh21
-rwxr-xr-xtests/mysql-basic-cnf6.sh21
-rwxr-xr-xtests/mysql-basic-vg.sh4
-rwxr-xr-xtests/mysql-basic.sh23
-rwxr-xr-xtests/mysqld-start.sh28
-rwxr-xr-xtests/mysqld-stop.sh14
-rwxr-xr-xtests/nested-call-shutdown.sh35
-rwxr-xr-xtests/no-dynstats-json.sh24
-rwxr-xr-xtests/no-dynstats.sh24
-rwxr-xr-xtests/no-parser-errmsg.sh25
-rwxr-xr-xtests/no-parser-vg.sh26
-rwxr-xr-xtests/now-unixtimestamp.sh32
-rwxr-xr-xtests/now-utc-casecmp.sh36
-rwxr-xr-xtests/now-utc-ymd.sh29
-rwxr-xr-xtests/now-utc.sh30
-rwxr-xr-xtests/now_family_utc.sh32
-rwxr-xr-xtests/omamqp1-basic-vg.sh3
-rwxr-xr-xtests/omamqp1-basic.sh70
-rw-r--r--tests/omamqp1-common.sh50
-rwxr-xr-xtests/omazureeventhubs-basic-vg.sh6
-rwxr-xr-xtests/omazureeventhubs-basic.sh123
-rwxr-xr-xtests/omazureeventhubs-interrupt-vg.sh5
-rwxr-xr-xtests/omazureeventhubs-interrupt.sh165
-rwxr-xr-xtests/omazureeventhubs-list.sh137
-rwxr-xr-xtests/omazureeventhubs-stress.sh137
-rwxr-xr-xtests/omfile-module-params.sh19
-rwxr-xr-xtests/omfile-null-filename.sh22
-rwxr-xr-xtests/omfile-outchannel-many.sh54
-rwxr-xr-xtests/omfile-outchannel.sh23
-rwxr-xr-xtests/omfile-read-only-errmsg.sh33
-rwxr-xr-xtests/omfile-read-only.sh35
-rwxr-xr-xtests/omfile-sizelimitcmd-many.sh36
-rwxr-xr-xtests/omfile-whitespace-filename.sh21
-rwxr-xr-xtests/omfile_both_files_set.sh45
-rwxr-xr-xtests/omfile_hup-vg.sh4
-rwxr-xr-xtests/omfile_hup.sh29
-rwxr-xr-xtests/omfwd-errfile-maxsize-filled.sh18
-rwxr-xr-xtests/omfwd-errfile-maxsize.sh17
-rwxr-xr-xtests/omfwd-keepalive.sh36
-rwxr-xr-xtests/omfwd-tls-invalid-permitExpiredCerts.sh13
-rwxr-xr-xtests/omfwd_fast_imuxsock.sh94
-rwxr-xr-xtests/omfwd_impstats-tcp.sh41
-rwxr-xr-xtests/omfwd_impstats-udp.sh35
-rwxr-xr-xtests/omhttp-auth-vg.sh3
-rwxr-xr-xtests/omhttp-auth.sh44
-rwxr-xr-xtests/omhttp-basic-vg.sh3
-rwxr-xr-xtests/omhttp-basic.sh42
-rwxr-xr-xtests/omhttp-batch-dynrestpath.sh49
-rwxr-xr-xtests/omhttp-batch-fail-with-400.sh51
-rwxr-xr-xtests/omhttp-batch-jsonarray-compress-vg.sh3
-rwxr-xr-xtests/omhttp-batch-jsonarray-compress.sh47
-rwxr-xr-xtests/omhttp-batch-jsonarray-retry-vg.sh3
-rwxr-xr-xtests/omhttp-batch-jsonarray-retry.sh77
-rwxr-xr-xtests/omhttp-batch-jsonarray-vg.sh3
-rwxr-xr-xtests/omhttp-batch-jsonarray.sh45
-rwxr-xr-xtests/omhttp-batch-kafkarest-retry-vg.sh3
-rwxr-xr-xtests/omhttp-batch-kafkarest-retry.sh77
-rwxr-xr-xtests/omhttp-batch-kafkarest.sh46
-rwxr-xr-xtests/omhttp-batch-lokirest-retry-vg.sh3
-rwxr-xr-xtests/omhttp-batch-lokirest-retry.sh77
-rwxr-xr-xtests/omhttp-batch-lokirest-vg.sh5
-rwxr-xr-xtests/omhttp-batch-lokirest.sh46
-rwxr-xr-xtests/omhttp-batch-newline.sh46
-rwxr-xr-xtests/omhttp-dynrestpath.sh46
-rwxr-xr-xtests/omhttp-httpheaderkey.sh43
-rwxr-xr-xtests/omhttp-multiplehttpheaders.sh45
-rwxr-xr-xtests/omhttp-retry-vg.sh3
-rwxr-xr-xtests/omhttp-retry.sh46
-rw-r--r--tests/omhttp_server.py135
-rwxr-xr-xtests/omjournal-abort-no-template.sh20
-rwxr-xr-xtests/omjournal-abort-template.sh21
-rwxr-xr-xtests/omjournal-basic-no-template.sh26
-rwxr-xr-xtests/omjournal-basic-template.sh32
-rwxr-xr-xtests/omkafka-vg.sh3
-rwxr-xr-xtests/omkafka.sh129
-rwxr-xr-xtests/omkafkadynakey.sh154
-rwxr-xr-xtests/ommail_errmsg_no_params.sh20
-rwxr-xr-xtests/omod-if-array-udp.sh29
-rwxr-xr-xtests/omod-if-array.sh29
-rwxr-xr-xtests/omprog-close-unresponsive-noterm.sh53
-rwxr-xr-xtests/omprog-close-unresponsive-vg.sh38
-rwxr-xr-xtests/omprog-close-unresponsive.sh55
-rwxr-xr-xtests/omprog-defaults-vg.sh29
-rwxr-xr-xtests/omprog-defaults.sh55
-rwxr-xr-xtests/omprog-feedback-mt.sh53
-rwxr-xr-xtests/omprog-feedback-timeout.sh63
-rwxr-xr-xtests/omprog-feedback-vg.sh32
-rwxr-xr-xtests/omprog-feedback.sh67
-rwxr-xr-xtests/omprog-if-error.sh41
-rwxr-xr-xtests/omprog-output-capture-mt.sh98
-rwxr-xr-xtests/omprog-output-capture-vg.sh5
-rwxr-xr-xtests/omprog-output-capture.sh57
-rwxr-xr-xtests/omprog-restart-terminated-outfile.sh135
-rwxr-xr-xtests/omprog-restart-terminated-vg.sh4
-rwxr-xr-xtests/omprog-restart-terminated.sh155
-rwxr-xr-xtests/omprog-single-instance-outfile.sh71
-rwxr-xr-xtests/omprog-single-instance-vg.sh4
-rwxr-xr-xtests/omprog-single-instance.sh63
-rwxr-xr-xtests/omprog-transactions-failed-commits.sh158
-rwxr-xr-xtests/omprog-transactions-failed-messages.sh159
-rwxr-xr-xtests/omprog-transactions-vg.sh37
-rwxr-xr-xtests/omprog-transactions.sh140
-rwxr-xr-xtests/omrabbitmq_data_1server-vg.sh4
-rwxr-xr-xtests/omrabbitmq_data_1server.sh48
-rwxr-xr-xtests/omrabbitmq_data_2servers.sh50
-rwxr-xr-xtests/omrabbitmq_error_server0.sh42
-rwxr-xr-xtests/omrabbitmq_error_server1.sh42
-rwxr-xr-xtests/omrabbitmq_error_server2.sh42
-rwxr-xr-xtests/omrabbitmq_error_server3.sh41
-rwxr-xr-xtests/omrabbitmq_json.sh45
-rwxr-xr-xtests/omrabbitmq_no_params.sh16
-rwxr-xr-xtests/omrabbitmq_params_invalid0.sh16
-rwxr-xr-xtests/omrabbitmq_params_invalid1.sh16
-rwxr-xr-xtests/omrabbitmq_params_invalid2.sh16
-rwxr-xr-xtests/omrabbitmq_params_invalid3.sh16
-rwxr-xr-xtests/omrabbitmq_params_missing0.sh16
-rwxr-xr-xtests/omrabbitmq_params_missing1.sh16
-rwxr-xr-xtests/omrabbitmq_params_missing2.sh16
-rwxr-xr-xtests/omrabbitmq_raw.sh40
-rwxr-xr-xtests/omrelp-invld-tlslib.sh15
-rw-r--r--tests/omrelp_dflt_port.c9
-rwxr-xr-xtests/omrelp_errmsg_no_connect.sh17
-rwxr-xr-xtests/omrelp_wrong_authmode.sh21
-rwxr-xr-xtests/omruleset-queue.sh45
-rwxr-xr-xtests/omruleset.sh34
-rwxr-xr-xtests/omsnmp_errmsg_no_params.sh20
-rwxr-xr-xtests/omstdout-basic.sh27
-rwxr-xr-xtests/omtcl.sh19
-rw-r--r--tests/omtcl.tcl9
-rwxr-xr-xtests/omudpspoof_errmsg_no_params.sh16
-rwxr-xr-xtests/omusrmsg-errmsg-no-params.sh14
-rwxr-xr-xtests/omusrmsg-noabort-vg.sh4
-rwxr-xr-xtests/omusrmsg-noabort.sh23
-rwxr-xr-xtests/operatingstate-basic.sh19
-rwxr-xr-xtests/operatingstate-empty.sh22
-rwxr-xr-xtests/operatingstate-unclean.sh25
-rw-r--r--tests/ourtail.c46
-rw-r--r--tests/override_getaddrinfo.c28
-rw-r--r--tests/override_gethostname.c22
-rw-r--r--tests/override_gethostname_nonfqdn.c14
-rwxr-xr-xtests/parsertest-parse-3164-buggyday-udp.sh32
-rwxr-xr-xtests/parsertest-parse-3164-buggyday.sh32
-rwxr-xr-xtests/parsertest-parse-nodate-udp.sh28
-rwxr-xr-xtests/parsertest-parse-nodate.sh27
-rwxr-xr-xtests/parsertest-parse1-udp.sh83
-rwxr-xr-xtests/parsertest-parse1.sh82
-rwxr-xr-xtests/parsertest-parse2-udp.sh31
-rwxr-xr-xtests/parsertest-parse2.sh31
-rwxr-xr-xtests/parsertest-parse3-udp.sh32
-rwxr-xr-xtests/parsertest-parse3.sh32
-rwxr-xr-xtests/parsertest-parse_8bit_escape-udp.sh31
-rwxr-xr-xtests/parsertest-parse_8bit_escape.sh31
-rwxr-xr-xtests/parsertest-parse_invld_regex-udp.sh30
-rwxr-xr-xtests/parsertest-parse_invld_regex.sh30
-rwxr-xr-xtests/parsertest-snare_ccoff_udp.sh28
-rwxr-xr-xtests/parsertest-snare_ccoff_udp2.sh32
-rwxr-xr-xtests/perctile-simple-vg.sh3
-rwxr-xr-xtests/perctile-simple.sh62
-rwxr-xr-xtests/pgsql-actq-mt-withpause-vg.sh40
-rwxr-xr-xtests/pgsql-actq-mt-withpause.sh39
-rwxr-xr-xtests/pgsql-basic-cnf6-vg.sh27
-rwxr-xr-xtests/pgsql-basic-cnf6.sh28
-rwxr-xr-xtests/pgsql-basic-threads-cnf6.sh30
-rwxr-xr-xtests/pgsql-basic-vg.sh25
-rwxr-xr-xtests/pgsql-basic.sh24
-rwxr-xr-xtests/pgsql-template-cnf6-vg.sh38
-rwxr-xr-xtests/pgsql-template-cnf6.sh37
-rwxr-xr-xtests/pgsql-template-threads-cnf6.sh36
-rwxr-xr-xtests/pgsql-template-vg.sh30
-rwxr-xr-xtests/pgsql-template.sh32
-rwxr-xr-xtests/pipe_noreader.sh36
-rwxr-xr-xtests/pipeaction.sh46
-rwxr-xr-xtests/pmdb2diag_parse.sh65
-rwxr-xr-xtests/pmlastmsg-udp.sh44
-rwxr-xr-xtests/pmlastmsg.sh44
-rwxr-xr-xtests/pmnormalize-basic-vg.sh4
-rwxr-xr-xtests/pmnormalize-basic.sh29
-rwxr-xr-xtests/pmnormalize-invld-rulebase-vg.sh4
-rwxr-xr-xtests/pmnormalize-invld-rulebase.sh15
-rwxr-xr-xtests/pmnormalize-neither_rule_rulebase-vg.sh4
-rwxr-xr-xtests/pmnormalize-neither_rule_rulebase.sh15
-rwxr-xr-xtests/pmnormalize-rule-vg.sh4
-rwxr-xr-xtests/pmnormalize-rule.sh29
-rwxr-xr-xtests/pmnormalize-rule_and_rulebase-vg.sh4
-rwxr-xr-xtests/pmnormalize-rule_and_rulebase.sh15
-rwxr-xr-xtests/pmnormalize-rule_invld-data-vg.sh4
-rwxr-xr-xtests/pmnormalize-rule_invld-data.sh28
-rwxr-xr-xtests/pmnull-basic.sh26
-rwxr-xr-xtests/pmnull-withparams.sh26
-rwxr-xr-xtests/pmrfc3164-AtSignsInHostname.sh28
-rwxr-xr-xtests/pmrfc3164-AtSignsInHostname_off.sh30
-rwxr-xr-xtests/pmrfc3164-defaultTag.sh29
-rwxr-xr-xtests/pmrfc3164-json.sh32
-rwxr-xr-xtests/pmrfc3164-msgFirstSpace.sh32
-rwxr-xr-xtests/pmrfc3164-tagEndingByColon.sh32
-rwxr-xr-xtests/pmsnare-ccbackslash-udp.sh38
-rwxr-xr-xtests/pmsnare-ccbackslash.sh39
-rwxr-xr-xtests/pmsnare-cccstyle-udp.sh41
-rwxr-xr-xtests/pmsnare-cccstyle.sh43
-rwxr-xr-xtests/pmsnare-ccdefault-udp.sh42
-rwxr-xr-xtests/pmsnare-ccdefault.sh42
-rwxr-xr-xtests/pmsnare-ccoff-udp.sh36
-rwxr-xr-xtests/pmsnare-ccoff.sh36
-rwxr-xr-xtests/pmsnare-default-udp.sh45
-rwxr-xr-xtests/pmsnare-default.sh45
-rwxr-xr-xtests/pmsnare-modoverride-udp.sh47
-rwxr-xr-xtests/pmsnare-modoverride.sh48
-rwxr-xr-xtests/privdrop_common.sh110
-rwxr-xr-xtests/privdropabortonidfail.sh41
-rwxr-xr-xtests/privdropabortonidfaillegacy.sh38
-rwxr-xr-xtests/privdropgroup.sh28
-rwxr-xr-xtests/privdropgroupid.sh22
-rwxr-xr-xtests/privdropuser.sh21
-rwxr-xr-xtests/privdropuserid.sh21
-rwxr-xr-xtests/prop-all-json-concurrency.sh34
-rwxr-xr-xtests/prop-jsonmesg-vg.sh23
-rwxr-xr-xtests/prop-programname-with-slashes.sh27
-rwxr-xr-xtests/prop-programname.sh20
-rwxr-xr-xtests/proprepltest-nolimittag-udp.sh34
-rwxr-xr-xtests/proprepltest-nolimittag.sh34
-rwxr-xr-xtests/proprepltest-rfctag-udp.sh34
-rwxr-xr-xtests/proprepltest-rfctag.sh34
-rwxr-xr-xtests/queue-direct-with-no-params.sh12
-rwxr-xr-xtests/queue-direct-with-params-given.sh12
-rwxr-xr-xtests/queue-encryption-da.sh34
-rwxr-xr-xtests/queue-encryption-disk.sh34
-rwxr-xr-xtests/queue-encryption-disk_keyfile-vg.sh37
-rwxr-xr-xtests/queue-encryption-disk_keyfile.sh35
-rwxr-xr-xtests/queue-encryption-disk_keyprog.sh39
-rwxr-xr-xtests/queue-minbatch-queuefull.sh22
-rwxr-xr-xtests/queue-minbatch.sh42
-rwxr-xr-xtests/queue-persist-drvr.sh54
-rwxr-xr-xtests/queue-persist.sh13
-rwxr-xr-xtests/queue_warnmsg-oversize.sh15
-rwxr-xr-xtests/random.sh30
-rw-r--r--tests/randomgen.c130
-rwxr-xr-xtests/rawmsg-after-pri.sh31
-rwxr-xr-xtests/rcvr_fail_restore.sh168
-rwxr-xr-xtests/relp_tls_certificate_not_found.sh30
-rwxr-xr-xtests/rfc5424parser-sp_at_msg_start.sh25
-rwxr-xr-xtests/rfc5424parser.sh24
-rwxr-xr-xtests/rs-cnum.sh26
-rwxr-xr-xtests/rs-int2hex.sh27
-rwxr-xr-xtests/rs-substring.sh26
-rwxr-xr-xtests/rs_optimizer_pri.sh28
-rwxr-xr-xtests/rscript-config_enable-off-vg.sh22
-rwxr-xr-xtests/rscript-config_enable-on.sh24
-rwxr-xr-xtests/rscript_backticks-vg.sh17
-rwxr-xr-xtests/rscript_backticks_empty_envvar-vg.sh16
-rwxr-xr-xtests/rscript_bare_var_root-empty.sh31
-rwxr-xr-xtests/rscript_bare_var_root.sh32
-rwxr-xr-xtests/rscript_compare-common.sh53
-rwxr-xr-xtests/rscript_compare_num-num-vg.sh5
-rwxr-xr-xtests/rscript_compare_num-num.sh4
-rwxr-xr-xtests/rscript_compare_num-numstr-vg.sh5
-rwxr-xr-xtests/rscript_compare_num-numstr.sh4
-rwxr-xr-xtests/rscript_compare_num-str-vg.sh5
-rwxr-xr-xtests/rscript_compare_num-str.sh4
-rwxr-xr-xtests/rscript_compare_numstr-num-vg.sh5
-rwxr-xr-xtests/rscript_compare_numstr-num.sh4
-rwxr-xr-xtests/rscript_compare_numstr-numstr-vg.sh5
-rwxr-xr-xtests/rscript_compare_numstr-numstr.sh4
-rwxr-xr-xtests/rscript_compare_numstr-str-vg.sh5
-rwxr-xr-xtests/rscript_compare_numstr-str.sh4
-rwxr-xr-xtests/rscript_compare_str-num-vg.sh5
-rwxr-xr-xtests/rscript_compare_str-num.sh4
-rwxr-xr-xtests/rscript_compare_str-numstr-vg.sh5
-rwxr-xr-xtests/rscript_compare_str-numstr.sh4
-rwxr-xr-xtests/rscript_compare_str-str-vg.sh5
-rwxr-xr-xtests/rscript_compare_str-str.sh4
-rwxr-xr-xtests/rscript_contains.sh17
-rwxr-xr-xtests/rscript_eq.sh29
-rwxr-xr-xtests/rscript_eq_var.sh72
-rwxr-xr-xtests/rscript_exists-not1.sh22
-rwxr-xr-xtests/rscript_exists-not2.sh22
-rwxr-xr-xtests/rscript_exists-not3.sh22
-rwxr-xr-xtests/rscript_exists-not4.sh22
-rwxr-xr-xtests/rscript_exists-yes.sh22
-rwxr-xr-xtests/rscript_exists-yes2.sh22
-rwxr-xr-xtests/rscript_field-vg.sh34
-rwxr-xr-xtests/rscript_field.sh26
-rwxr-xr-xtests/rscript_format_time.sh45
-rwxr-xr-xtests/rscript_ge.sh28
-rwxr-xr-xtests/rscript_ge_var.sh75
-rwxr-xr-xtests/rscript_get_property-vg.sh4
-rwxr-xr-xtests/rscript_get_property.sh70
-rwxr-xr-xtests/rscript_gt.sh27
-rwxr-xr-xtests/rscript_gt_var.sh69
-rwxr-xr-xtests/rscript_hash32-vg.sh28
-rwxr-xr-xtests/rscript_hash32.sh27
-rwxr-xr-xtests/rscript_hash64-vg.sh28
-rwxr-xr-xtests/rscript_hash64.sh27
-rwxr-xr-xtests/rscript_http_request-vg.sh4
-rwxr-xr-xtests/rscript_http_request.sh47
-rwxr-xr-xtests/rscript_int2Hex.sh27
-rwxr-xr-xtests/rscript_ipv42num.sh51
-rwxr-xr-xtests/rscript_is_time.sh81
-rwxr-xr-xtests/rscript_le.sh27
-rwxr-xr-xtests/rscript_le_var.sh75
-rwxr-xr-xtests/rscript_lt.sh27
-rwxr-xr-xtests/rscript_lt_var.sh69
-rwxr-xr-xtests/rscript_ne.sh33
-rwxr-xr-xtests/rscript_ne_var.sh75
-rwxr-xr-xtests/rscript_num2ipv4.sh42
-rwxr-xr-xtests/rscript_number_comparison_LE-vg.sh3
-rwxr-xr-xtests/rscript_number_comparison_LE.sh24
-rwxr-xr-xtests/rscript_number_comparison_LT.sh24
-rwxr-xr-xtests/rscript_optimizer1.sh27
-rwxr-xr-xtests/rscript_parse_json-vg.sh25
-rwxr-xr-xtests/rscript_parse_json.sh24
-rwxr-xr-xtests/rscript_parse_time.sh122
-rw-r--r--tests/rscript_parse_time_get-ts.py152
-rwxr-xr-xtests/rscript_previous_action_suspended.sh27
-rwxr-xr-xtests/rscript_prifilt.sh25
-rwxr-xr-xtests/rscript_privdropgroup.sh21
-rwxr-xr-xtests/rscript_privdropgroupid.sh21
-rwxr-xr-xtests/rscript_privdropuser.sh21
-rwxr-xr-xtests/rscript_privdropuserid.sh21
-rwxr-xr-xtests/rscript_random.sh25
-rwxr-xr-xtests/rscript_re_extract.sh25
-rwxr-xr-xtests/rscript_re_extract_i.sh21
-rwxr-xr-xtests/rscript_re_match-dbl_quotes.sh16
-rwxr-xr-xtests/rscript_re_match.sh21
-rwxr-xr-xtests/rscript_re_match_i.sh21
-rwxr-xr-xtests/rscript_replace.sh29
-rwxr-xr-xtests/rscript_replace_complex.sh31
-rwxr-xr-xtests/rscript_ruleset_call.sh37
-rwxr-xr-xtests/rscript_ruleset_call_indirect-basic.sh23
-rwxr-xr-xtests/rscript_ruleset_call_indirect-invld.sh32
-rwxr-xr-xtests/rscript_ruleset_call_indirect-var.sh25
-rwxr-xr-xtests/rscript_script_error.sh30
-rwxr-xr-xtests/rscript_set_memleak-vg.sh34
-rwxr-xr-xtests/rscript_set_modify.sh26
-rwxr-xr-xtests/rscript_set_unset_invalid_var.sh41
-rwxr-xr-xtests/rscript_stop.sh28
-rwxr-xr-xtests/rscript_stop2.sh33
-rwxr-xr-xtests/rscript_str2num_negative.sh25
-rwxr-xr-xtests/rscript_substring.sh32
-rwxr-xr-xtests/rscript_trim-vg.sh89
-rwxr-xr-xtests/rscript_trim.sh88
-rwxr-xr-xtests/rscript_unaffected_reset.sh27
-rwxr-xr-xtests/rscript_unflatten_arg1_unsuitable-vg.sh3
-rwxr-xr-xtests/rscript_unflatten_arg1_unsuitable.sh30
-rwxr-xr-xtests/rscript_unflatten_arg2_invalid-vg.sh3
-rwxr-xr-xtests/rscript_unflatten_arg2_invalid.sh31
-rwxr-xr-xtests/rscript_unflatten_conflict1-vg.sh3
-rwxr-xr-xtests/rscript_unflatten_conflict1.sh43
-rwxr-xr-xtests/rscript_unflatten_conflict2-vg.sh3
-rwxr-xr-xtests/rscript_unflatten_conflict2.sh44
-rwxr-xr-xtests/rscript_unflatten_conflict3-vg.sh3
-rwxr-xr-xtests/rscript_unflatten_conflict3.sh43
-rwxr-xr-xtests/rscript_unflatten_key_truncated-vg.sh3
-rwxr-xr-xtests/rscript_unflatten_key_truncated.sh42
-rwxr-xr-xtests/rscript_unflatten_non_object-vg.sh3
-rwxr-xr-xtests/rscript_unflatten_non_object.sh37
-rwxr-xr-xtests/rscript_unflatten_object-vg.sh3
-rwxr-xr-xtests/rscript_unflatten_object.sh39
-rwxr-xr-xtests/rscript_unflatten_object_exclamation-vg.sh3
-rwxr-xr-xtests/rscript_unflatten_object_exclamation.sh34
-rwxr-xr-xtests/rscript_wrap2.sh25
-rwxr-xr-xtests/rscript_wrap3.sh25
-rwxr-xr-xtests/rsf_getenv.sh23
-rwxr-xr-xtests/ruleset-direct-queue.sh27
-rwxr-xr-xtests/rulesetmultiqueue-v6.sh62
-rwxr-xr-xtests/rulesetmultiqueue.sh77
-rw-r--r--tests/set-envvars.in1
-rwxr-xr-xtests/smtradfile-vg.sh4
-rwxr-xr-xtests/smtradfile.sh14
-rwxr-xr-xtests/sndrcv.sh49
-rwxr-xr-xtests/sndrcv_drvr.sh2
-rwxr-xr-xtests/sndrcv_drvr_noexit.sh49
-rwxr-xr-xtests/sndrcv_dtls_anon_ciphers.sh67
-rwxr-xr-xtests/sndrcv_dtls_certvalid-vg.sh9
-rwxr-xr-xtests/sndrcv_dtls_certvalid.sh91
-rwxr-xr-xtests/sndrcv_dtls_certvalid_ciphers.sh74
-rwxr-xr-xtests/sndrcv_dtls_certvalid_missing.sh82
-rwxr-xr-xtests/sndrcv_dtls_certvalid_permitted.sh94
-rwxr-xr-xtests/sndrcv_failover.sh67
-rwxr-xr-xtests/sndrcv_gzip.sh44
-rwxr-xr-xtests/sndrcv_kafka.sh125
-rwxr-xr-xtests/sndrcv_kafka_multi_topics.sh171
-rwxr-xr-xtests/sndrcv_omsnmpv1_udp.sh46
-rwxr-xr-xtests/sndrcv_omsnmpv1_udp_dynsource.sh55
-rwxr-xr-xtests/sndrcv_omsnmpv1_udp_invalidoid.sh46
-rwxr-xr-xtests/sndrcv_omudpspoof-bigmsg.sh83
-rwxr-xr-xtests/sndrcv_omudpspoof.sh65
-rwxr-xr-xtests/sndrcv_omudpspoof_nonstdpt.sh66
-rwxr-xr-xtests/sndrcv_ossl_cert_chain.sh76
-rwxr-xr-xtests/sndrcv_relp-vg-rcvr.sh59
-rwxr-xr-xtests/sndrcv_relp-vg-sender.sh60
-rwxr-xr-xtests/sndrcv_relp.sh43
-rwxr-xr-xtests/sndrcv_relp_dflt_pt.sh54
-rwxr-xr-xtests/sndrcv_relp_rebind.sh48
-rwxr-xr-xtests/sndrcv_relp_tls-cfgcmd.sh70
-rwxr-xr-xtests/sndrcv_relp_tls.sh45
-rwxr-xr-xtests/sndrcv_relp_tls_certvalid.sh65
-rwxr-xr-xtests/sndrcv_relp_tls_chainedcert.sh70
-rwxr-xr-xtests/sndrcv_relp_tls_prio.sh44
-rwxr-xr-xtests/sndrcv_tls_anon_hostname.sh62
-rwxr-xr-xtests/sndrcv_tls_anon_ipv4.sh65
-rwxr-xr-xtests/sndrcv_tls_anon_ipv6.sh67
-rwxr-xr-xtests/sndrcv_tls_anon_rebind.sh64
-rwxr-xr-xtests/sndrcv_tls_certless_clientonly.sh61
-rwxr-xr-xtests/sndrcv_tls_certvalid.sh60
-rwxr-xr-xtests/sndrcv_tls_certvalid_action_level.sh63
-rwxr-xr-xtests/sndrcv_tls_certvalid_expired.sh63
-rwxr-xr-xtests/sndrcv_tls_certvalid_expired_defaultmode.sh61
-rwxr-xr-xtests/sndrcv_tls_certvalid_revoked.sh67
-rwxr-xr-xtests/sndrcv_tls_client_missing_cert.sh65
-rwxr-xr-xtests/sndrcv_tls_gtls_serveranon_gtls_clientanon.sh48
-rwxr-xr-xtests/sndrcv_tls_gtls_serveranon_ossl_clientanon.sh66
-rwxr-xr-xtests/sndrcv_tls_gtls_servercert_gtls_clientanon.sh56
-rwxr-xr-xtests/sndrcv_tls_gtls_servercert_gtls_clientanon_legacy.sh65
-rwxr-xr-xtests/sndrcv_tls_gtls_servercert_ossl_clientanon.sh65
-rwxr-xr-xtests/sndrcv_tls_ossl_anon_ciphers.sh72
-rwxr-xr-xtests/sndrcv_tls_ossl_anon_ipv4.sh66
-rwxr-xr-xtests/sndrcv_tls_ossl_anon_ipv6.sh4
-rwxr-xr-xtests/sndrcv_tls_ossl_anon_rebind.sh78
-rwxr-xr-xtests/sndrcv_tls_ossl_certvalid.sh4
-rwxr-xr-xtests/sndrcv_tls_ossl_certvalid_action_level.sh4
-rwxr-xr-xtests/sndrcv_tls_ossl_certvalid_ciphers.sh75
-rwxr-xr-xtests/sndrcv_tls_ossl_certvalid_expired.sh61
-rwxr-xr-xtests/sndrcv_tls_ossl_certvalid_revoked.sh6
-rwxr-xr-xtests/sndrcv_tls_ossl_certvalid_tlscommand.sh81
-rwxr-xr-xtests/sndrcv_tls_ossl_serveranon_gtls_clientanon.sh66
-rwxr-xr-xtests/sndrcv_tls_ossl_serveranon_ossl_clientanon.sh57
-rwxr-xr-xtests/sndrcv_tls_ossl_servercert_gtls_clientanon.sh66
-rwxr-xr-xtests/sndrcv_tls_ossl_servercert_ossl_clientanon.sh66
-rwxr-xr-xtests/sndrcv_tls_priorityString.sh68
-rwxr-xr-xtests/sndrcv_udp.sh61
-rwxr-xr-xtests/sndrcv_udp_nonstdpt.sh48
-rwxr-xr-xtests/sndrcv_udp_nonstdpt_v6.sh53
-rwxr-xr-xtests/snmptrapreceiver.py104
-rwxr-xr-xtests/sparse_array_lookup_table-vg.sh5
-rwxr-xr-xtests/sparse_array_lookup_table.sh64
-rwxr-xr-xtests/stats-cee-vg.sh36
-rwxr-xr-xtests/stats-cee.sh28
-rwxr-xr-xtests/stats-json-es.sh29
-rwxr-xr-xtests/stats-json-vg.sh37
-rwxr-xr-xtests/stats-json.sh28
-rwxr-xr-xtests/stop-localvar.sh30
-rwxr-xr-xtests/stop-msgvar.sh30
-rwxr-xr-xtests/stop.sh25
-rwxr-xr-xtests/stop_when_array_has_element.sh31
-rwxr-xr-xtests/suspend-omfwd-via-file.sh51
-rwxr-xr-xtests/suspend-via-file.sh68
-rw-r--r--tests/syslog_caller.c151
-rwxr-xr-xtests/tabescape_dflt-udp.sh29
-rwxr-xr-xtests/tabescape_dflt.sh29
-rwxr-xr-xtests/tabescape_off-udp.sh32
-rwxr-xr-xtests/tabescape_off.sh28
-rwxr-xr-xtests/tabescape_on.sh28
-rwxr-xr-xtests/tcp-msgreduc-vg.sh28
-rwxr-xr-xtests/tcp_forwarding_dflt_tpl.sh40
-rwxr-xr-xtests/tcp_forwarding_ns_tpl.sh52
-rwxr-xr-xtests/tcp_forwarding_retries.sh41
-rwxr-xr-xtests/tcp_forwarding_tpl.sh38
-rw-r--r--tests/tcpflood.c2108
-rwxr-xr-xtests/tcpflood_wrong_option_output.sh18
-rwxr-xr-xtests/template-const-jsonf.sh19
-rwxr-xr-xtests/template-json.sh30
-rwxr-xr-xtests/template-pos-from-to-lowercase.sh19
-rwxr-xr-xtests/template-pos-from-to-missing-jsonvar.sh26
-rwxr-xr-xtests/template-pos-from-to-oversize-lowercase.sh26
-rwxr-xr-xtests/template-pos-from-to-oversize.sh56
-rwxr-xr-xtests/template-pos-from-to.sh19
-rwxr-xr-xtests/template-pure-json.sh19
-rwxr-xr-xtests/template-topos-neg.sh19
-rw-r--r--tests/test.mmdbbin0 -> 432 bytes
-rw-r--r--tests/test_id.c39
-rwxr-xr-xtests/test_id_usage_output.sh14
-rwxr-xr-xtests/testsuites/abort-uncleancfg-goodcfg.conf9
-rw-r--r--tests/testsuites/action-tx-errfile.result25
-rw-r--r--tests/testsuites/complex_replace_input4
-rw-r--r--tests/testsuites/date_time_msg2
-rw-r--r--tests/testsuites/docroot/file.txt1
-rw-r--r--tests/testsuites/dynstats_empty_input7
-rw-r--r--tests/testsuites/dynstats_input6
-rw-r--r--tests/testsuites/dynstats_input_12
-rw-r--r--tests/testsuites/dynstats_input_22
-rw-r--r--tests/testsuites/dynstats_input_32
-rw-r--r--tests/testsuites/dynstats_input_more_010
-rw-r--r--tests/testsuites/dynstats_input_more_13
-rw-r--r--tests/testsuites/dynstats_input_more_25
-rw-r--r--tests/testsuites/es.yml95
-rw-r--r--tests/testsuites/htpasswd1
-rw-r--r--tests/testsuites/imfile-old-state-file_imfile-state_.-rsyslog.input15
-rw-r--r--tests/testsuites/imhttp-large-data.txt250
-rw-r--r--tests/testsuites/imptcp_framing_regex-oversize.testdata22
-rw-r--r--tests/testsuites/imptcp_framing_regex.testdata18
-rw-r--r--tests/testsuites/imptcp_multi_line.testdata16
-rw-r--r--tests/testsuites/incltest.d/include.conf2
-rw-r--r--tests/testsuites/include-std-omfile-action.conf3
-rw-r--r--tests/testsuites/include-std1-omfile-action.conf5
-rw-r--r--tests/testsuites/include-std2-omfile-action.conf2
-rw-r--r--tests/testsuites/invalid.conf3
-rw-r--r--tests/testsuites/json_array_input1
-rw-r--r--tests/testsuites/json_nonarray_input3
-rw-r--r--tests/testsuites/json_object_input1
-rw-r--r--tests/testsuites/kafka-server.dep_wrk1.properties69
-rw-r--r--tests/testsuites/kafka-server.dep_wrk2.properties69
-rw-r--r--tests/testsuites/kafka-server.dep_wrk3.properties69
-rw-r--r--tests/testsuites/kafka-server.properties69
-rwxr-xr-xtests/testsuites/mmexternal-SegFault-mm-python.py84
-rw-r--r--tests/testsuites/mmnormalize_processing_tests.rulebase14
-rw-r--r--tests/testsuites/mmnormalize_regex.rulebase1
-rw-r--r--tests/testsuites/mmnormalize_tokenized.rulebase5
-rw-r--r--tests/testsuites/mmnormalize_variable.rulebase1
-rw-r--r--tests/testsuites/msgvar-concurrency-array-event.tags.rulebase11
-rw-r--r--tests/testsuites/msgvar-concurrency-array.rulebase11
-rw-r--r--tests/testsuites/mysql-select-msg.sql2
-rw-r--r--tests/testsuites/mysql-truncate.sql2
-rw-r--r--tests/testsuites/no_octet_counted.testdata20
-rwxr-xr-xtests/testsuites/omprog-close-unresponsive-bin.sh32
-rwxr-xr-xtests/testsuites/omprog-defaults-bin.sh14
-rwxr-xr-xtests/testsuites/omprog-feedback-bin.sh33
-rwxr-xr-xtests/testsuites/omprog-feedback-mt-bin.sh31
-rwxr-xr-xtests/testsuites/omprog-feedback-timeout-bin.sh49
-rwxr-xr-xtests/testsuites/omprog-output-capture-bin.sh16
-rwxr-xr-xtests/testsuites/omprog-output-capture-mt-bin.py35
-rwxr-xr-xtests/testsuites/omprog-restart-terminated-bin.sh49
-rwxr-xr-xtests/testsuites/omprog-single-instance-bin.sh25
-rwxr-xr-xtests/testsuites/omprog-transactions-bin.sh60
-rw-r--r--tests/testsuites/pgsql-basic.sql30
-rw-r--r--tests/testsuites/pgsql-select-msg.sql1
-rw-r--r--tests/testsuites/pgsql-select-syslogtag.sql1
-rw-r--r--tests/testsuites/pmnormalize_basic.rulebase1
-rw-r--r--tests/testsuites/regex_input1
-rw-r--r--tests/testsuites/spframingfix.testdata20
-rw-r--r--tests/testsuites/stop_when_array_has_elem_input3
-rw-r--r--tests/testsuites/tokenized_input5
-rw-r--r--tests/testsuites/valid.conf3
-rw-r--r--tests/testsuites/variable_leading_underscore.conf2
-rw-r--r--tests/testsuites/wrap3_input1
-rw-r--r--tests/testsuites/x.509/ca-key.pem182
-rw-r--r--tests/testsuites/x.509/ca.pem27
-rw-r--r--tests/testsuites/x.509/ca.srl1
-rw-r--r--tests/testsuites/x.509/client-cert-new.pem102
-rw-r--r--tests/testsuites/x.509/client-cert.pem27
-rw-r--r--tests/testsuites/x.509/client-expired-cert.pem25
-rw-r--r--tests/testsuites/x.509/client-expired-key.pem134
-rw-r--r--tests/testsuites/x.509/client-key.pem182
-rw-r--r--tests/testsuites/x.509/client-new.csr23
-rw-r--r--tests/testsuites/x.509/client-revoked-key.pem28
-rw-r--r--tests/testsuites/x.509/client-revoked-valid.pem92
-rw-r--r--tests/testsuites/x.509/client-revoked.csr18
-rw-r--r--tests/testsuites/x.509/client-revoked.pem92
-rw-r--r--tests/testsuites/x.509/crl.pem14
-rw-r--r--tests/testsuites/x.509/index.txt3
-rw-r--r--tests/testsuites/x.509/index.txt.attr1
-rw-r--r--tests/testsuites/x.509/machine-cert.pem27
-rw-r--r--tests/testsuites/x.509/machine-key.pem182
-rw-r--r--tests/testsuites/x.509/newcerts/01.pem92
-rw-r--r--tests/testsuites/x.509/newcerts/02.pem92
-rw-r--r--tests/testsuites/x.509/newcerts/03.pem92
-rw-r--r--tests/testsuites/x.509/newcerts/04.pem102
-rw-r--r--tests/testsuites/x.509/openssl-cmds.sh11
-rw-r--r--tests/testsuites/x.509/openssl.cnf41
-rw-r--r--tests/testsuites/x.509/serial1
-rw-r--r--tests/testsuites/xlate.lkp_tbl5
-rw-r--r--tests/testsuites/xlate_array.lkp_tbl6
-rw-r--r--tests/testsuites/xlate_array_empty_table.lkp_tbl6
-rw-r--r--tests/testsuites/xlate_array_misuse.lkp_tbl6
-rw-r--r--tests/testsuites/xlate_array_more.lkp_tbl7
-rw-r--r--tests/testsuites/xlate_array_more_misuse.lkp_tbl7
-rw-r--r--tests/testsuites/xlate_array_more_with_duplicates_and_nomatch.lkp_tbl13
-rw-r--r--tests/testsuites/xlate_array_no_index.lkp_tbl8
-rw-r--r--tests/testsuites/xlate_array_no_table.lkp_tbl5
-rw-r--r--tests/testsuites/xlate_array_no_value.lkp_tbl8
-rw-r--r--tests/testsuites/xlate_empty_file.lkp_tbl0
-rw-r--r--tests/testsuites/xlate_incorrect_type.lkp_tbl8
-rw-r--r--tests/testsuites/xlate_incorrect_version.lkp_tbl8
-rw-r--r--tests/testsuites/xlate_invalid_json.lkp_tbl4
-rw-r--r--tests/testsuites/xlate_more.lkp_tbl6
-rw-r--r--tests/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl12
-rw-r--r--tests/testsuites/xlate_sparseArray_empty_table.lkp_tbl6
-rw-r--r--tests/testsuites/xlate_sparseArray_no_index.lkp_tbl8
-rw-r--r--tests/testsuites/xlate_sparseArray_no_table.lkp_tbl5
-rw-r--r--tests/testsuites/xlate_sparseArray_no_value.lkp_tbl8
-rw-r--r--tests/testsuites/xlate_sparse_array.lkp_tbl6
-rw-r--r--tests/testsuites/xlate_sparse_array_more.lkp_tbl7
-rw-r--r--tests/testsuites/xlate_sparse_array_more_with_duplicates_and_nomatch.lkp_tbl12
-rw-r--r--tests/testsuites/xlate_string_empty_table.lkp_tbl6
-rw-r--r--tests/testsuites/xlate_string_no_index.lkp_tbl8
-rw-r--r--tests/testsuites/xlate_string_no_table.lkp_tbl5
-rw-r--r--tests/testsuites/xlate_string_no_value.lkp_tbl8
-rw-r--r--tests/testsuites/zoo.cfg5
-rw-r--r--tests/testsuites/zoo.dep_wrk1.cfg5
-rw-r--r--tests/testsuites/zoo.dep_wrk2.cfg5
-rw-r--r--tests/testsuites/zoo.dep_wrk3.cfg5
-rwxr-xr-xtests/threadingmq.sh35
-rwxr-xr-xtests/threadingmqaq.sh47
-rwxr-xr-xtests/timegenerated-dateordinal-invld.sh62
-rwxr-xr-xtests/timegenerated-dateordinal.sh168
-rwxr-xr-xtests/timegenerated-utc-legacy.sh36
-rwxr-xr-xtests/timegenerated-utc.sh42
-rwxr-xr-xtests/timegenerated-uxtimestamp-invld.sh65
-rwxr-xr-xtests/timegenerated-uxtimestamp.sh207
-rwxr-xr-xtests/timegenerated-ymd.sh32
-rwxr-xr-xtests/timereported-utc-legacy.sh24
-rwxr-xr-xtests/timereported-utc-vg.sh4
-rwxr-xr-xtests/timereported-utc.sh27
-rwxr-xr-xtests/timestamp-3164.sh51
-rwxr-xr-xtests/timestamp-3339.sh33
-rwxr-xr-xtests/timestamp-isoweek.sh24
-rwxr-xr-xtests/timestamp-mysql.sh19
-rwxr-xr-xtests/timestamp-pgsql.sh20
-rwxr-xr-xtests/timestamp-subseconds.sh24
-rw-r--r--tests/tls-certs/ca-fail.pem3
-rw-r--r--tests/tls-certs/ca-key.pem190
-rw-r--r--tests/tls-certs/ca.pem29
-rw-r--r--tests/tls-certs/cert-fail.pem3
-rw-r--r--tests/tls-certs/cert.pem31
-rw-r--r--tests/tls-certs/certchained.pem60
-rw-r--r--tests/tls-certs/key-fail.pem40
-rw-r--r--tests/tls-certs/key.pem190
-rw-r--r--tests/travis/trusty.supp10
-rwxr-xr-xtests/udp-msgreduc-orgmsg-vg.sh35
-rwxr-xr-xtests/udp-msgreduc-vg.sh35
-rwxr-xr-xtests/unused_lookup_table-vg.sh27
-rwxr-xr-xtests/urlencode.py14
-rwxr-xr-xtests/uxsock_simple.sh46
-rw-r--r--tests/uxsockrcvr.c192
-rwxr-xr-xtests/validation-run.sh29
-rwxr-xr-xtests/variable_leading_underscore.sh13
-rw-r--r--tests/with_space.mmdbbin0 -> 432 bytes
-rwxr-xr-xtests/wr_large_async.sh31
-rwxr-xr-xtests/wr_large_sync.sh31
-rwxr-xr-xtests/wtpShutdownAll-assertionFailure.sh29
-rwxr-xr-xtests/zstd-vg.sh4
-rwxr-xr-xtests/zstd.sh38
1290 files changed, 61875 insertions, 0 deletions
diff --git a/tests/1.rstest b/tests/1.rstest
new file mode 100644
index 0000000..4716e8b
--- /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: push_const test 1[cstr]
+00000001: push_msgvar var[cstr]
+00000002: cmp_!=
+00000003: push_msgvar severity[cstr]
+00000004: push_const 4[nbr]
+00000005: unary_minus
+00000006: push_const 5[nbr]
+00000007: add
+00000008: push_const 3[nbr]
+00000009: push_const 2[nbr]
+00000010: unary_minus
+00000011: mul
+00000012: sub
+00000013: cmp_==
+00000014: push_msgvar fromhost[cstr]
+00000015: push_const 127.0.0.1[cstr]
+00000016: cmp_==
+00000017: and
+00000018: or
+$$$
diff --git a/tests/2.rstest b/tests/2.rstest
new file mode 100644
index 0000000..f0e8205
--- /dev/null
+++ b/tests/2.rstest
@@ -0,0 +1,10 @@
+# a simple RainerScript test
+result: 0
+in:
+$msg contains 'test' then
+$$$
+out:
+00000000: push_msgvar msg[cstr]
+00000001: push_const test[cstr]
+00000002: contains
+$$$
diff --git a/tests/3.rstest b/tests/3.rstest
new file mode 100644
index 0000000..e75d975
--- /dev/null
+++ b/tests/3.rstest
@@ -0,0 +1,21 @@
+# a simple RainerScript test
+result: 0
+in:
+strlen($msg & strlen('abc')) > 20 +30 + -40 then
+$$$
+out:
+00000000: push_msgvar msg[cstr]
+00000001: push_const abc[cstr]
+00000002: push_const 1[nbr]
+00000003: func_call strlen
+00000004: strconcat
+00000005: push_const 1[nbr]
+00000006: func_call strlen
+00000007: push_const 20[nbr]
+00000008: push_const 30[nbr]
+00000009: add
+00000010: push_const 40[nbr]
+00000011: unary_minus
+00000012: add
+00000013: cmp_>
+$$$
diff --git a/tests/CI/centos6-9.supp b/tests/CI/centos6-9.supp
new file mode 100644
index 0000000..e77e3e1
--- /dev/null
+++ b/tests/CI/centos6-9.supp
@@ -0,0 +1,32 @@
+{
+ CentOS 6.9 problem in either helgrind or system lib
+ Helgrind:Misc
+ fun:pthread_cond_destroy_WRK
+ fun:pthread_cond_destroy@*
+ fun:qqueueDestruct
+ fun:actionDestruct
+ fun:cnfstmtDestruct
+ fun:cnfstmtDestructLst
+ fun:cnfstmtDestruct
+ fun:cnfstmtDestructLst
+ fun:doDestructCnfStmt
+ fun:llExecFunc
+ fun:destructAllActions
+ fun:main
+}
+{
+ libcrypto issue - only seen on Centos 6 so pretty sure false positive
+ Memcheck:Leak
+ fun:malloc
+ fun:CRYPTO_malloc
+ fun:EC_KEY_new
+ fun:EC_KEY_new_by_curve_name
+ fun:osslAnonInit
+ fun:SetAuthMode
+ fun:LstnInit
+ fun:LstnInit
+ fun:LstnInit
+ fun:initTCPListener
+ fun:create_tcp_socket
+ fun:doOpenLstnSocks
+}
diff --git a/tests/CI/centos7.supp b/tests/CI/centos7.supp
new file mode 100644
index 0000000..424dd72
--- /dev/null
+++ b/tests/CI/centos7.supp
@@ -0,0 +1,9 @@
+{
+ CentOS 7 system lib memleak
+ Memcheck:Free
+ fun:free
+ fun:__libc_freeres
+ fun:_vgnU_freeres
+ fun:__run_exit_handlers
+ ...
+}
diff --git a/tests/CI/gcov.supp b/tests/CI/gcov.supp
new file mode 100644
index 0000000..61269dd
--- /dev/null
+++ b/tests/CI/gcov.supp
@@ -0,0 +1,6 @@
+{
+ gcc -coverage exceptions
+ Helgrind:Race
+ fun:__gcov_merge_add
+ ...
+}
diff --git a/tests/CI/ubuntu20.04.supp b/tests/CI/ubuntu20.04.supp
new file mode 100644
index 0000000..2638a7f
--- /dev/null
+++ b/tests/CI/ubuntu20.04.supp
@@ -0,0 +1,42 @@
+{
+ librdkafka issue
+ Memcheck:Leak
+ match-leak-kinds: definite
+ fun:malloc
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+ obj:*
+ fun:checkInstance
+ fun:activateCnf
+ fun:tellModulesActivateConfig
+ fun:activate
+ fun:initAll
+}
+
+{
+ librdkafka issue
+ Memcheck:Leak
+ match-leak-kinds: definite
+ fun:malloc
+ ...
+ obj:*
+ fun:checkInstance
+ fun:activateCnf
+ fun:tellModulesActivateConfig
+ fun:activate
+ fun:initAll
+ fun:main
+}
+
+{
+ invalid atexit call - seems to stem back to libcurl
+ Helgrind:Misc
+ ...
+ fun:_dl_fini
+ fun:__run_exit_handlers
+ fun:exit
+ fun:(below main)
+}
diff --git a/tests/DevNull.cfgtest b/tests/DevNull.cfgtest
new file mode 100644
index 0000000..bc43693
--- /dev/null
+++ b/tests/DevNull.cfgtest
@@ -0,0 +1,2 @@
+rsyslogd: CONFIG ERROR: there are no active actions configured. Inputs will run, but no output whatsoever is created. [try https://www.rsyslog.com/e/2103 ]
+rsyslogd: EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file!
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..70b0a60
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,3148 @@
+TEST_EXTENSIONS=.sh
+
+if ENABLE_TESTBENCH
+
+CLEANFILES=\
+ *_*.conf \
+ rsyslog*.started work-*.conf rsyslog.random.data \
+ rsyslog*.pid.save xlate*.lkp_tbl \
+ log log* *.log \
+ work \
+ test-spool test-logdir stat-file1 \
+ rsyslog.pipe rsyslog.input.* \
+ rsyslog.input rsyslog.input.* imfile-state:* omkafka-failed.data \
+ rsyslog.input-symlink.log rsyslog-link.*.log targets \
+ HOSTNAME \
+ rstb_* \
+ zookeeper.pid \
+ tmp.qi nocert
+
+CLEANFILES+= \
+ IN_AUTO_DEBUG
+# IN_AUTO_DEBUG should be deleted each time make check is run, but
+# there exists no such hook. Se we at least delete it on make clean.
+
+
+pkglib_LTLIBRARIES =
+
+pkglib_LTLIBRARIES += liboverride_gethostname.la
+liboverride_gethostname_la_SOURCES = override_gethostname.c
+liboverride_gethostname_la_CFLAGS =
+liboverride_gethostname_la_LDFLAGS = -avoid-version -shared
+
+pkglib_LTLIBRARIES += liboverride_gethostname_nonfqdn.la
+liboverride_gethostname_nonfqdn_la_SOURCES = override_gethostname_nonfqdn.c
+liboverride_gethostname_nonfqdn_la_CFLAGS =
+liboverride_gethostname_nonfqdn_la_LDFLAGS = -avoid-version -shared
+
+pkglib_LTLIBRARIES += liboverride_getaddrinfo.la
+liboverride_getaddrinfo_la_SOURCES = override_getaddrinfo.c
+liboverride_getaddrinfo_la_CFLAGS =
+liboverride_getaddrinfo_la_LDFLAGS = -avoid-version -shared
+
+# TODO: reenable TESTRUNS = rt_init rscript
+check_PROGRAMS = $(TESTRUNS) ourtail tcpflood chkseq msleep randomgen \
+ diagtalker uxsockrcvr syslog_caller inputfilegen minitcpsrv \
+ omrelp_dflt_port \
+ mangle_qi \
+ have_relpSrvSetOversizeMode \
+ have_relpEngineSetTLSLibByName \
+ have_relpSrvSetTlsConfigCmd \
+ check_relpEngineVersion \
+ test_id
+if ENABLE_JOURNAL_TESTS
+if ENABLE_IMJOURNAL
+check_PROGRAMS += journal_print
+endif
+endif # if ENABLE_JOURNAL_TESTS
+TESTS = $(TESTRUNS)
+
+if ENABLE_ELASTICSEARCH_TESTS_MINIMAL
+TESTS += \
+ es-duplicated-ruleset.sh
+# the following test need to be serialized:
+TESTS += \
+ es-basic-es6.0.sh \
+ es-basic-es7.14.sh \
+ es-basic.sh \
+ es-basic-bulk.sh
+es-basic-es7.14.log: es-basic-es6.0.log
+es-basic.log: es-basic-es7.14.log
+es-basic-bulk.log: es-basic.log
+es-basic-server.log: es-basic-bulk.log
+
+# special "test" for stopping ES once all ES tests are done
+TESTS += elasticsearch-stop.sh
+elasticsearch-stop.log: es-basic-bulk.log
+
+
+if HAVE_VALGRIND
+TESTS += \
+ es-duplicated-ruleset-vg.sh \
+ es-basic-vg.sh
+es-basic-vg.log: es-basic-bulk.log
+# for next if block:
+es-basic-server.log: es-basic-vg.log
+elasticsearch-stop.log: es-basic-vg.log
+if ENABLE_HELGRIND
+TESTS += \
+ es-basic-vgthread.sh
+es-basic-vgthread.log: es-basic-vg.log
+# for next if block:
+es-basic-server.log: es-basic-vgthread.log
+elasticsearch-stop.log: es-basic-vgthread.log
+endif # ENABLE_HELGRIND
+endif # HAVE_VALGRIND
+endif # ENABLE_ELASTICSEARCH_TESTS_MINIMAL
+
+if ENABLE_ELASTICSEARCH_TESTS
+TESTS += \
+ es-basic-server.sh \
+ es-execOnlyWhenPreviousSuspended.sh \
+ es-maxbytes-bulk.sh \
+ es-basic-errfile-empty.sh \
+ es-basic-errfile-popul.sh \
+ es-bulk-errfile-empty.sh \
+ es-bulk-errfile-popul.sh \
+ es-searchType-empty.sh \
+ diskqueue-multithread-es.sh \
+ es-writeoperation.sh
+
+es-basic-server.log: es-basic-bulk.log
+es-execOnlyWhenPreviousSuspended.log: es-basic-server.log
+es-maxbytes-bulk.log: es-execOnlyWhenPreviousSuspended.log
+es-basic-errfile-empty.log: es-maxbytes-bulk.log
+es-basic-errfile-popul.log: es-basic-errfile-empty.log
+es-bulk-errfile-empty.log: es-basic-errfile-popul.log
+es-bulk-errfile-popul.log: es-bulk-errfile-empty.log
+es-searchType-empty.log: es-bulk-errfile-popul.log
+diskqueue-multithread-es.log: es-searchType-empty.log
+es-writeoperation.log: diskqueue-multithread-es.log
+elasticsearch-stop.log: es-writeoperation.log
+
+if ENABLE_IMPSTATS
+TESTS += \
+ es-basic-ha.sh \
+ es-bulk-retry.sh
+
+es-basic-ha.log: es-writeoperation.log
+es-bulk-retry.log: es-basic-ha.log
+elasticsearch-stop.log: es-bulk-retry.log
+endif
+if ENABLE_IMFILE
+TESTS += \
+ es-bulk-errfile-popul-def-format.sh \
+ es-bulk-errfile-popul-erronly.sh \
+ es-bulk-errfile-popul-erronly-interleaved.sh \
+ es-bulk-errfile-popul-def-interleaved.sh
+
+es-bulk-errfile-popul-def-format.log: es-bulk-retry.log
+es-bulk-errfile-popul-erronly.log: es-bulk-errfile-popul-def-format.log
+es-bulk-errfile-popul-erronly-interleaved.log: es-bulk-errfile-popul-erronly.log
+es-bulk-errfile-popul-def-interleaved.log: es-bulk-errfile-popul-erronly-interleaved.log
+elasticsearch-stop.log: es-bulk-errfile-popul-def-interleaved.log
+endif
+if HAVE_VALGRIND
+TESTS += \
+ es-basic-bulk-vg.sh \
+ es-basic-ha-vg.sh
+
+es-basic-bulk-vg.log: es-writeoperation.log
+es-basic-bulk-vg.log: es-bulk-retry.log
+es-basic-bulk-vg.log: es-bulk-errfile-popul-def-interleaved.log
+es-basic-ha-vg.log: es-basic-bulk-vg.log
+elasticsearch-stop.log: es-basic-ha-vg.log
+endif
+endif # if ENABLE_ELASTICSEARCH_TESTS
+
+
+
+if ENABLE_DEFAULT_TESTS
+TESTS += \
+ immark.sh \
+ immark-inputname.sh \
+ immark-ruleset.sh \
+ immark-ruleset-custom-msg.sh \
+ operatingstate-basic.sh \
+ operatingstate-empty.sh \
+ operatingstate-unclean.sh \
+ smtradfile.sh \
+ loadbalance.sh \
+ empty-hostname.sh \
+ timestamp-3164.sh \
+ timestamp-3339.sh \
+ timestamp-isoweek.sh \
+ timestamp-mysql.sh \
+ timestamp-pgsql.sh \
+ timestamp-subseconds.sh \
+ msleep_usage_output.sh \
+ mangle_qi_usage_output.sh \
+ minitcpsrv_usage_output.sh \
+ test_id_usage_output.sh \
+ prop-programname.sh \
+ prop-programname-with-slashes.sh \
+ hostname-with-slash-pmrfc5424.sh \
+ hostname-with-slash-pmrfc3164.sh \
+ hostname-with-slash-dflt-invld.sh \
+ func-substring-invld-startpos.sh \
+ func-substring-large-endpos.sh \
+ func-substring-large-neg-endpos.sh \
+ func-substring-relative-endpos.sh \
+ hostname-with-slash-dflt-slash-valid.sh \
+ empty-app-name.sh \
+ stop-localvar.sh \
+ stop-msgvar.sh \
+ glbl-ruleset-queue-defaults.sh \
+ glbl-internalmsg_severity-info-shown.sh \
+ glbl-internalmsg_severity-debug-shown.sh \
+ glbl-internalmsg_severity-debug-not_shown.sh \
+ glbl-umask.sh \
+ glbl-unloadmodules.sh \
+ glbl-invld-param.sh \
+ glbl_setenv_2_vars.sh \
+ glbl_setenv_err.sh \
+ glbl_setenv_err_too_long.sh \
+ glbl_setenv.sh \
+ mmexternal-SegFault.sh \
+ nested-call-shutdown.sh \
+ dnscache-TTL-0.sh \
+ invalid_nested_include.sh \
+ omfwd-tls-invalid-permitExpiredCerts.sh \
+ omfwd-keepalive.sh \
+ omusrmsg-errmsg-no-params.sh \
+ omusrmsg-noabort.sh \
+ omfile-module-params.sh \
+ omfile-read-only-errmsg.sh \
+ omfile-null-filename.sh \
+ omfile-whitespace-filename.sh \
+ omfile-read-only.sh \
+ omfile-outchannel.sh \
+ omfile_both_files_set.sh \
+ omfile_hup.sh \
+ msgvar-concurrency.sh \
+ localvar-concurrency.sh \
+ exec_tpl-concurrency.sh \
+ rscript_privdropuser.sh \
+ rscript_privdropuserid.sh \
+ rscript_privdropgroup.sh \
+ rscript_privdropgroupid.sh \
+ privdropuser.sh \
+ privdropuserid.sh \
+ privdropgroup.sh \
+ privdropgroupid.sh \
+ privdropabortonidfail.sh \
+ privdropabortonidfaillegacy.sh \
+ json-nonstring.sh \
+ json-onempty-at-end.sh \
+ template-json.sh \
+ template-pure-json.sh \
+ template-pos-from-to.sh \
+ template-pos-from-to-lowercase.sh \
+ template-pos-from-to-oversize.sh \
+ template-pos-from-to-oversize-lowercase.sh \
+ template-pos-from-to-missing-jsonvar.sh \
+ template-const-jsonf.sh \
+ template-topos-neg.sh \
+ fac_authpriv.sh \
+ fac_local0.sh \
+ fac_local7.sh \
+ fac_mail.sh \
+ fac_news.sh \
+ fac_ftp.sh \
+ fac_ntp.sh \
+ fac_uucp.sh \
+ fac_invld1.sh \
+ fac_invld2.sh \
+ fac_invld3.sh \
+ fac_invld4_rfc5424.sh \
+ rfc5424parser-sp_at_msg_start.sh \
+ compresssp.sh \
+ compresssp-stringtpl.sh \
+ rawmsg-after-pri.sh \
+ rfc5424parser.sh \
+ pmrfc3164-msgFirstSpace.sh \
+ pmrfc3164-AtSignsInHostname.sh \
+ pmrfc3164-AtSignsInHostname_off.sh \
+ pmrfc3164-tagEndingByColon.sh \
+ pmrfc3164-defaultTag.sh \
+ pmrfc3164-json.sh \
+ tcp_forwarding_tpl.sh \
+ tcp_forwarding_dflt_tpl.sh \
+ tcp_forwarding_retries.sh \
+ mainq_actq_DA.sh \
+ queue_warnmsg-oversize.sh \
+ queue-minbatch.sh \
+ queue-minbatch-queuefull.sh \
+ queue-direct-with-no-params.sh \
+ queue-direct-with-params-given.sh \
+ arrayqueue.sh \
+ global_vars.sh \
+ no-parser-errmsg.sh \
+ da-mainmsg-q.sh \
+ validation-run.sh \
+ msgdup.sh \
+ msgdup_props.sh \
+ empty-ruleset.sh \
+ ruleset-direct-queue.sh \
+ imtcp-listen-port-file-2.sh \
+ allowed-sender-tcp-ok.sh \
+ allowed-sender-tcp-fail.sh \
+ allowed-sender-tcp-hostname-ok.sh \
+ allowed-sender-tcp-hostname-fail.sh \
+ imtcp-discard-truncated-msg.sh \
+ imtcp-basic.sh \
+ imtcp-basic-hup.sh \
+ imtcp-maxFrameSize.sh \
+ imtcp-msg-truncation-on-number.sh \
+ imtcp-msg-truncation-on-number2.sh \
+ imtcp-NUL.sh \
+ imtcp-NUL-rawmsg.sh \
+ imtcp_incomplete_frame_at_end.sh \
+ imtcp-multiport.sh \
+ imtcp-bigmessage-octetcounting.sh \
+ imtcp-bigmessage-octetstuffing.sh \
+ da-queue-persist.sh \
+ daqueue-persist.sh \
+ daqueue-invld-qi.sh \
+ daqueue-dirty-shutdown.sh \
+ diskq-rfc5424.sh \
+ diskqueue.sh \
+ diskqueue-fsync.sh \
+ diskqueue-full.sh \
+ diskqueue-fail.sh \
+ diskqueue-non-unique-prefix.sh \
+ rulesetmultiqueue.sh \
+ rulesetmultiqueue-v6.sh \
+ manytcp.sh \
+ rsf_getenv.sh \
+ msg-deadlock-headerless-noappname.sh \
+ imtcp_conndrop.sh \
+ imtcp_addtlframedelim.sh \
+ imtcp_no_octet_counted.sh \
+ imtcp_addtlframedelim_on_input.sh \
+ imtcp_spframingfix.sh \
+ imtcp-connection-msg-recieved.sh \
+ sndrcv.sh \
+ sndrcv_failover.sh \
+ sndrcv_gzip.sh \
+ sndrcv_udp_nonstdpt.sh \
+ sndrcv_udp_nonstdpt_v6.sh \
+ imudp_thread_hang.sh \
+ sndrcv_udp_nonstdpt_v6.sh \
+ asynwr_simple.sh \
+ asynwr_simple_2.sh \
+ asynwr_timeout.sh \
+ asynwr_timeout_2.sh \
+ asynwr_small.sh \
+ asynwr_tinybuf.sh \
+ wr_large_async.sh \
+ wr_large_sync.sh \
+ asynwr_deadlock.sh \
+ asynwr_deadlock_2.sh \
+ asynwr_deadlock2.sh \
+ asynwr_deadlock4.sh \
+ asynwr_dynfile_flushtxend-off.sh \
+ abort-uncleancfg-goodcfg.sh \
+ abort-uncleancfg-goodcfg-check.sh \
+ abort-uncleancfg-badcfg-check.sh \
+ abort-uncleancfg-badcfg-check_1.sh \
+ variable_leading_underscore.sh \
+ gzipwr_hup_multi_file.sh \
+ gzipwr_hup_single_file.sh \
+ gzipwr_rscript.sh \
+ gzipwr_flushInterval.sh \
+ gzipwr_flushOnTXEnd.sh \
+ gzipwr_large.sh \
+ gzipwr_large_dynfile.sh \
+ gzipwr_hup.sh \
+ dynfile_invld_async.sh \
+ dynfile_invld_sync.sh \
+ dynfile_invalid2.sh \
+ complex1.sh \
+ queue-persist.sh \
+ pipeaction.sh \
+ execonlyonce.sh \
+ execonlywhenprevsuspended.sh \
+ execonlywhenprevsuspended2.sh \
+ execonlywhenprevsuspended3.sh \
+ execonlywhenprevsuspended4.sh \
+ execonlywhenprevsuspended_multiwrkr.sh \
+ execonlywhenprevsuspended-queue.sh \
+ execonlywhenprevsuspended-nonsusp.sh \
+ execonlywhenprevsuspended-nonsusp-queue.sh \
+ pipe_noreader.sh \
+ dircreate_dflt.sh \
+ dircreate_off.sh \
+ imuxsock_legacy.sh \
+ imuxsock_logger.sh \
+ imuxsock_logger_ratelimit.sh \
+ imuxsock_logger_ruleset.sh \
+ imuxsock_logger_ruleset_ratelimit.sh \
+ imuxsock_logger_err.sh \
+ imuxsock_logger_parserchain.sh \
+ imuxsock_traillf.sh \
+ imuxsock_ccmiddle.sh \
+ imuxsock_logger_syssock.sh \
+ imuxsock_traillf_syssock.sh \
+ imuxsock_ccmiddle_syssock.sh \
+ discard-rptdmsg.sh \
+ discard-allmark.sh \
+ discard.sh \
+ stop.sh \
+ failover-async.sh \
+ failover-double.sh \
+ failover-basic.sh \
+ failover-rptd.sh \
+ failover-no-rptd.sh \
+ failover-no-basic.sh \
+ suspend-via-file.sh \
+ suspend-omfwd-via-file.sh \
+ externalstate-failed-rcvr.sh \
+ rcvr_fail_restore.sh \
+ rscript_contains.sh \
+ rscript_bare_var_root.sh \
+ rscript_bare_var_root-empty.sh \
+ rscript_ipv42num.sh \
+ rscript_field.sh \
+ rscript_stop.sh \
+ rscript_stop2.sh \
+ rscript_prifilt.sh \
+ rscript_optimizer1.sh \
+ rscript_ruleset_call.sh \
+ rscript_ruleset_call_indirect-basic.sh \
+ rscript_ruleset_call_indirect-var.sh \
+ rscript_ruleset_call_indirect-invld.sh \
+ rscript_set_unset_invalid_var.sh \
+ rscript_set_modify.sh \
+ rscript_unaffected_reset.sh \
+ rscript_replace_complex.sh \
+ rscript_wrap2.sh \
+ rscript_wrap3.sh \
+ rscript_re_extract_i.sh \
+ rscript_re_extract.sh \
+ rscript_re_match_i.sh \
+ rscript_re_match.sh \
+ rscript_re_match-dbl_quotes.sh \
+ rscript_eq.sh \
+ rscript_eq_var.sh \
+ rscript_ge.sh \
+ rscript_ge_var.sh \
+ rscript_gt.sh \
+ rscript_gt_var.sh \
+ rscript_le.sh \
+ rscript_le_var.sh \
+ rscript_lt.sh \
+ rscript_lt_var.sh \
+ rscript_ne.sh \
+ rscript_ne_var.sh \
+ rscript_number_comparison_LE.sh \
+ rscript_number_comparison_LT.sh \
+ rscript_compare_str-numstr.sh \
+ rscript_compare_str-num.sh \
+ rscript_compare_numstr-str.sh \
+ rscript_compare_num-str.sh \
+ rscript_compare_numstr-numstr.sh \
+ rscript_compare_numstr-num.sh \
+ rscript_compare_num-numstr.sh \
+ rscript_compare_num-num.sh \
+ rscript_compare_str-str.sh \
+ rscript_num2ipv4.sh \
+ rscript_int2Hex.sh \
+ rscript_trim.sh \
+ rscript_substring.sh \
+ rscript_format_time.sh \
+ rscript_parse_time.sh \
+ rscript_is_time.sh \
+ rscript_script_error.sh \
+ rscript_parse_json.sh \
+ rscript_previous_action_suspended.sh \
+ rscript_str2num_negative.sh \
+ rscript_exists-yes.sh \
+ rscript_exists-yes2.sh \
+ rscript_exists-not1.sh \
+ rscript_exists-not2.sh \
+ rscript_exists-not3.sh \
+ rscript_exists-not4.sh \
+ rscript-config_enable-on.sh \
+ rscript_get_property.sh \
+ config_output-o-option.sh \
+ rs-cnum.sh \
+ rs-substring.sh \
+ rs-int2hex.sh \
+ empty-prop-comparison.sh \
+ rs_optimizer_pri.sh \
+ cee_simple.sh \
+ cee_diskqueue.sh \
+ incltest.sh \
+ incltest_dir.sh \
+ incltest_dir_wildcard.sh \
+ incltest_dir_empty_wildcard.sh \
+ linkedlistqueue.sh \
+ lookup_table.sh \
+ lookup_table-hup-backgrounded.sh \
+ lookup_table_no_hup_reload.sh \
+ key_dereference_on_uninitialized_variable_space.sh \
+ array_lookup_table.sh \
+ sparse_array_lookup_table.sh \
+ lookup_table_bad_configs.sh \
+ lookup_table_rscript_reload.sh \
+ lookup_table_rscript_reload_without_stub.sh \
+ config_multiple_include.sh \
+ include-obj-text-from-file.sh \
+ include-obj-text-from-file-noexist.sh \
+ multiple_lookup_tables.sh \
+ parsertest-parse1.sh \
+ parsertest-parse1-udp.sh \
+ parsertest-parse2.sh \
+ parsertest-parse2-udp.sh \
+ parsertest-parse_8bit_escape.sh \
+ parsertest-parse_8bit_escape-udp.sh \
+ parsertest-parse3.sh \
+ parsertest-parse3-udp.sh \
+ parsertest-parse_invld_regex.sh \
+ parsertest-parse_invld_regex-udp.sh \
+ parsertest-parse-3164-buggyday.sh \
+ parsertest-parse-3164-buggyday-udp.sh \
+ parsertest-parse-nodate.sh \
+ parsertest-parse-nodate-udp.sh \
+ parsertest-snare_ccoff_udp.sh \
+ parsertest-snare_ccoff_udp2.sh
+
+if ENABLE_LIBZSTD
+TESTS += \
+ zstd.sh
+if HAVE_VALGRIND
+TESTS += \
+ zstd-vg.sh
+endif # if HAVE_VALGRIND
+endif
+
+if ENABLE_LIBGCRYPT
+TESTS += \
+ queue-encryption-disk.sh \
+ queue-encryption-disk_keyfile.sh \
+ queue-encryption-disk_keyprog.sh \
+ queue-encryption-da.sh
+endif # ENABLE_LIBGCRYPT
+if HAVE_VALGRIND
+TESTS += \
+ omusrmsg-noabort-vg.sh \
+ omfile_hup-vg.sh \
+ gzipwr_hup-vg.sh \
+ tcpflood_wrong_option_output.sh \
+ imtcp-octet-framing-too-long-vg.sh \
+ smtradfile-vg.sh \
+ dnscache-TTL-0-vg.sh \
+ include-obj-outside-control-flow-vg.sh \
+ include-obj-in-if-vg.sh \
+ include-obj-text-vg.sh \
+ rscript_parse_json-vg.sh \
+ rscript_backticks-vg.sh \
+ rscript_backticks_empty_envvar-vg.sh \
+ rscript-config_enable-off-vg.sh \
+ rscript_get_property-vg.sh \
+ prop-jsonmesg-vg.sh \
+ mmexternal-InvldProg-vg.sh \
+ internal-errmsg-memleak-vg.sh \
+ glbl-oversizeMsg-log-vg.sh \
+ rscript_set_memleak-vg.sh \
+ no-parser-vg.sh \
+ discard-rptdmsg-vg.sh \
+ discard-allmark-vg.sh \
+ failover-basic-vg.sh \
+ failover-rptd-vg.sh \
+ failover-no-basic-vg.sh \
+ failover-no-rptd-vg.sh \
+ timereported-utc-vg.sh \
+ udp-msgreduc-vg.sh \
+ udp-msgreduc-orgmsg-vg.sh \
+ tcp-msgreduc-vg.sh \
+ rscript_field-vg.sh \
+ rscript_number_comparison_LE-vg.sh \
+ rscript_compare_str-str-vg.sh \
+ rscript_compare_str-num-vg.sh \
+ rscript_compare_str-numstr-vg.sh \
+ rscript_compare_num-str-vg.sh \
+ rscript_compare_numstr-str-vg.sh \
+ rscript_compare_numstr-num-vg.sh \
+ rscript_compare_numstr-numstr-vg.sh \
+ rscript_compare_num-num-vg.sh \
+ rscript_compare_num-numstr-vg.sh \
+ unused_lookup_table-vg.sh \
+ lookup_table-vg.sh \
+ lookup_table_no_hup_reload-vg.sh \
+ array_lookup_table-vg.sh \
+ array_lookup_table_misuse-vg.sh \
+ sparse_array_lookup_table-vg.sh \
+ lookup_table_bad_configs-vg.sh \
+ lookup_table_rscript_reload-vg.sh \
+ lookup_table_rscript_reload_without_stub-vg.sh \
+ multiple_lookup_tables-vg.sh \
+ fac_local0-vg.sh \
+ badqi.sh \
+ threadingmq.sh \
+ threadingmqaq.sh \
+ func-substring-invld-startpos-vg.sh \
+ rscript_trim-vg.sh
+if ENABLE_LIBGCRYPT
+TESTS += \
+ queue-encryption-disk_keyfile-vg.sh
+endif # ENABLE_LIBGCRYPT
+endif # HAVE_VALGRIND
+endif # ENABLE_DEFAULT_TESTS
+
+if ENABLE_SNMP
+TESTS += \
+ omsnmp_errmsg_no_params.sh
+if ENABLE_SNMP_TESTS
+TESTS += \
+ sndrcv_omsnmpv1_udp.sh \
+ sndrcv_omsnmpv1_udp_dynsource.sh \
+ sndrcv_omsnmpv1_udp_invalidoid.sh
+endif # if ENABLE_SNMP_TESTS
+endif # if ENABLE_SNMP
+
+if ENABLE_MMUTF8FIX
+TESTS += \
+ mmutf8fix_no_error.sh
+endif # if ENABLE_MAIL
+
+if ENABLE_MAIL
+TESTS += \
+ ommail_errmsg_no_params.sh
+endif # if ENABLE_MAIL
+
+if ENABLE_MMANON
+TESTS += \
+ mmanon_with_debug.sh \
+ mmanon_random_32_ipv4.sh \
+ mmanon_random_cons_32_ipv4.sh \
+ mmanon_recognize_ipv4.sh \
+ mmanon_zero_12_ipv4.sh \
+ mmanon_zero_33_ipv4.sh \
+ mmanon_zero_8_ipv4.sh \
+ mmanon_simple_12_ipv4.sh \
+ mmanon_simple_33_ipv4.sh \
+ mmanon_simple_8_ipv4.sh \
+ mmanon_simple_mallformed_ipv4.sh \
+ mmanon_random_128_ipv6.sh \
+ mmanon_zero_128_ipv6.sh \
+ mmanon_zero_96_ipv6.sh \
+ mmanon_random_cons_128_ipv6.sh \
+ mmanon_zero_50_ipv6.sh \
+ mmanon_recognize_ipv6.sh \
+ mmanon_zero_64_ipv6.sh \
+ mmanon_both_modes_compatible.sh \
+ mmanon_recognize_ipembedded.sh \
+ mmanon_ipv6_port.sh \
+ mmanon_random_cons_128_ipembedded.sh
+endif # if ENABLE_MMANON
+
+if ENABLE_CLICKHOUSE_TESTS
+TESTS += \
+ clickhouse-start.sh \
+ clickhouse-basic.sh \
+ clickhouse-dflt-tpl.sh \
+ clickhouse-retry-error.sh \
+ clickhouse-load.sh \
+ clickhouse-bulk.sh \
+ clickhouse-bulk-load.sh \
+ clickhouse-limited-batch.sh \
+ clickhouse-select.sh \
+ clickhouse-errorfile.sh \
+ clickhouse-wrong-quotation-marks.sh \
+ clickhouse-wrong-template-option.sh \
+ clickhouse-wrong-insert-syntax.sh
+
+clickhouse-basic.log: clickhouse-start.log
+clickhouse-dflt-tpl.log: clickhouse-basic.log
+clickhouse-retry-error.log: clickhouse-dflt-tpl.log
+clickhouse-load.log: clickhouse-retry-error.log
+clickhouse-bulk.log: clickhouse-load.log
+clickhouse-bulk-load.log: clickhouse-bulk.log
+clickhouse-limited-batch.log: clickhouse-bulk-load.log
+clickhouse-select.log: clickhouse-limited-batch.log
+clickhouse-errorfile.log: clickhouse-select.log
+clickhouse-wrong-quotation-marks.log: clickhouse-errorfile.log
+clickhouse-wrong-template-option.log: clickhouse-wrong-quotation-marks.log
+clickhouse-wrong-insert-syntax.log: clickhouse-wrong-template-option.log
+clickhouse-stop.log: clickhouse-wrong-insert-syntax.log
+
+if HAVE_VALGRIND
+TESTS += \
+ clickhouse-basic-vg.sh \
+ clickhouse-load-vg.sh \
+ clickhouse-bulk-vg.sh \
+ clickhouse-bulk-load-vg.sh
+
+clickhouse-basic-vg.log: clickhouse-wrong-insert-syntax.log
+clickhouse-load-vg.log: clickhouse-basic-vg.log
+clickhouse-bulk-vg.log: clickhouse-load-vg.log
+clickhouse-bulk-load-vg.log: clickhouse-bulk-vg.log
+clickhouse-stop.log: clickhouse-bulk-load-vg.log
+endif # VALGRIND
+
+TESTS += clickhouse-stop.sh
+endif # CLICKHOUSE_TESTS
+
+
+if ENABLE_LIBFAKETIME
+TESTS += \
+ now_family_utc.sh \
+ now-utc.sh \
+ now-utc-ymd.sh \
+ now-utc-casecmp.sh \
+ now-unixtimestamp.sh \
+ timegenerated-ymd.sh \
+ timegenerated-uxtimestamp.sh \
+ timegenerated-uxtimestamp-invld.sh \
+ timegenerated-dateordinal.sh \
+ timegenerated-dateordinal-invld.sh \
+ timegenerated-utc.sh \
+ timegenerated-utc-legacy.sh \
+ timereported-utc.sh \
+ timereported-utc-legacy.sh
+# now come faketime tests that utilize mmnormalize - aka "no endif here"
+if ENABLE_MMNORMALIZE
+TESTS += \
+ mmnormalize_processing_test1.sh \
+ mmnormalize_processing_test2.sh \
+ mmnormalize_processing_test3.sh \
+ mmnormalize_processing_test4.sh
+endif
+endif
+
+if ENABLE_PGSQL
+if ENABLE_PGSQL_TESTS
+TESTS += \
+ pgsql-basic.sh \
+ pgsql-basic-cnf6.sh \
+ pgsql-basic-threads-cnf6.sh \
+ pgsql-template.sh \
+ pgsql-template-cnf6.sh \
+ pgsql-actq-mt-withpause.sh \
+ pgsql-template-threads-cnf6.sh
+
+pgsql-basic-cnf6.log: pgsql-basic.log
+pgsql-basic-threads-cnf6.log: pgsql-basic-cnf6.log
+pgsql-template.log: pgsql-basic-threads-cnf6.log
+pgsql-template-cnf6.log: pgsql-template.log
+pgsql-actq-mt-withpause.log: pgsql-template-cnf6.log
+pgsql-template-threads-cnf6.log: pgsql-actq-mt-withpause.log
+if HAVE_VALGRIND
+TESTS += \
+ pgsql-basic-vg.sh \
+ pgsql-template-vg.sh \
+ pgsql-basic-cnf6-vg.sh \
+ pgsql-template-cnf6-vg.sh \
+ pgsql-actq-mt-withpause-vg.sh
+
+pgsql-basic-vg.log: pgsql-template-threads-cnf6.log
+pgsql-template-vg.log: pgsql-basic-vg.log
+pgsql-basic-cnf6-vg.log: pgsql-template-vg.log
+pgsql-template-cnf6-vg.log: pgsql-basic-cnf6-vg.log
+pgsql-actq-mt-withpause-vg.log: pgsql-template-cnf6-vg.log
+endif
+endif
+endif
+
+if ENABLE_MYSQL_TESTS
+TESTS += \
+ mysqld-start.sh \
+ mysql-basic.sh \
+ mysql-basic-cnf6.sh \
+ mysql-asyn.sh \
+ mysql-actq-mt.sh \
+ mysql-actq-mt-withpause.sh \
+ action-tx-single-processing.sh \
+ action-tx-errfile-maxsize.sh \
+ action-tx-errfile.sh
+
+mysql-basic.log: mysqld-start.log
+mysql-basic-cnf6.log: mysqld-start.log
+mysql-asyn.log: mysqld-start.log
+mysql-actq-mt.log: mysqld-start.log
+mysql-actq-mt-withpause.log: mysqld-start.log
+action-tx-single-processing.log: mysqld-start.log
+action-tx-errfile.log: mysqld-start.log
+
+mysqld-stop.log: mysql-basic.log \
+ mysql-basic-cnf6.log \
+ mysql-asyn.log \
+ mysql-actq-mt.log \
+ mysql-actq-mt-withpause.log \
+ action-tx-single-processing.log \
+ action-tx-errfile.log
+
+if HAVE_VALGRIND
+TESTS += \
+ mysql-basic-vg.sh \
+ mysql-asyn-vg.sh \
+ mysql-actq-mt-withpause-vg.sh
+mysql-basic-vg.log: mysqld-start.log
+mysql-asyn-vg.log: mysqld-start.log
+mysql-actq-mt-withpause-vg.log: mysqld-start.log
+
+mysqld-stop.log: mysql-basic-vg.log \
+ mysql-asyn-vg.log \
+ mysql-actq-mt-withpause-vg.log
+endif
+
+if ENABLE_OMLIBDBI # we piggy-back on MYSQL_TESTS as we need the same environment
+TESTS += \
+ libdbi-basic.sh \
+ libdbi-asyn.sh
+libdbi-basic.log: mysqld-start.log
+libdbi-asyn.log: mysqld-start.log
+mysqld-stop.log: libdbi-basic.log \
+ libdbi-asyn.log
+if HAVE_VALGRIND
+TESTS += \
+ libdbi-basic-vg.sh
+libdbi-basic-vg.log: mysqld-start.log
+mysqld-stop.log: libdbi-basic-vg.log
+endif
+endif
+TESTS += mysqld-stop.sh
+endif # MYSQL_TESTS
+
+if ENABLE_FMHTTP
+TESTS += \
+ rscript_http_request.sh
+if HAVE_VALGRIND
+TESTS += \
+ rscript_http_request-vg.sh
+endif # HAVE_VALGRIND
+endif # ENABLE_FMHTTP
+
+
+if ENABLE_ROOT_TESTS
+TESTS += \
+ sndrcv_udp.sh \
+ imuxsock_logger_root.sh \
+ imuxsock_traillf_root.sh \
+ imuxsock_ccmiddle_root.sh \
+ imklog_permitnonkernelfacility_root.sh
+if ENABLE_IP
+TESTS += tcp_forwarding_ns_tpl.sh
+endif
+if HAVE_VALGRIND
+TESTS += \
+ mmexternal-SegFault-empty-jroot-vg.sh
+endif
+endif
+
+if ENABLE_JOURNAL_TESTS
+if ENABLE_IMJOURNAL
+TESTS += \
+ imjournal-basic.sh \
+ imjournal-statefile.sh
+if HAVE_VALGRIND
+TESTS += \
+ imjournal-basic-vg.sh \
+ imjournal-statefile-vg.sh
+endif
+endif
+
+if ENABLE_OMJOURNAL
+TESTS += \
+ omjournal-abort-template.sh \
+ omjournal-abort-no-template.sh \
+ omjournal-basic-template.sh \
+ omjournal-basic-no-template.sh
+endif
+endif #if ENABLE_JOURNAL_TESTS
+
+if ENABLE_IMPROG
+TESTS += \
+ improg_errmsg_no_params.sh \
+ improg_prog_simple.sh \
+ improg_prog_confirm.sh \
+ improg_prog_confirm_killonclose.sh \
+ improg_prog_killonclose.sh \
+ improg_simple_multi.sh
+if HAVE_VALGRIND
+TESTS += \
+ improg_errmsg_no_params-vg.sh \
+ improg_prog_simple-vg.sh
+endif # ENABLE_IMPROG
+endif
+
+if ENABLE_MMDARWIN
+TESTS += \
+ mmdarwin_errmsg_no_params.sh \
+ mmdarwin_errmsg_no_sock.sh
+if HAVE_VALGRIND
+TESTS += \
+ mmdarwin_errmsg_no_sock-vg.sh
+endif # HAVE_VALGRIND
+endif # ENABLE_IMPROG
+
+if ENABLE_OMPROG
+TESTS += \
+ omprog-defaults.sh \
+ omprog-output-capture.sh \
+ omprog-output-capture-mt.sh \
+ omprog-feedback.sh \
+ omprog-feedback-mt.sh \
+ omprog-feedback-timeout.sh \
+ omprog-close-unresponsive.sh \
+ omprog-close-unresponsive-noterm.sh \
+ omprog-restart-terminated.sh \
+ omprog-restart-terminated-outfile.sh \
+ omprog-single-instance.sh \
+ omprog-single-instance-outfile.sh \
+ omprog-transactions.sh \
+ omprog-if-error.sh \
+ omprog-transactions-failed-messages.sh \
+ omprog-transactions-failed-commits.sh
+if HAVE_VALGRIND
+TESTS += \
+ omprog-defaults-vg.sh \
+ omprog-output-capture-vg.sh \
+ omprog-feedback-vg.sh \
+ omprog-close-unresponsive-vg.sh \
+ omprog-restart-terminated-vg.sh \
+ omprog-single-instance-vg.sh \
+ omprog-transactions-vg.sh
+endif
+endif
+
+if ENABLE_OMHTTP
+TESTS += \
+ omhttp-auth.sh \
+ omhttp-basic.sh \
+ omhttp-batch-fail-with-400.sh \
+ omhttp-batch-jsonarray-compress.sh \
+ omhttp-batch-jsonarray-retry.sh \
+ omhttp-batch-jsonarray.sh \
+ omhttp-batch-kafkarest-retry.sh \
+ omhttp-batch-kafkarest.sh \
+ omhttp-batch-lokirest-retry.sh \
+ omhttp-batch-lokirest.sh \
+ omhttp-batch-newline.sh \
+ omhttp-retry.sh \
+ omhttp-httpheaderkey.sh \
+ omhttp-multiplehttpheaders.sh \
+ omhttp-dynrestpath.sh \
+ omhttp-batch-dynrestpath.sh
+if HAVE_VALGRIND
+TESTS += \
+ omhttp-auth-vg.sh \
+ omhttp-basic-vg.sh \
+ omhttp-batch-jsonarray-compress-vg.sh \
+ omhttp-batch-jsonarray-retry-vg.sh \
+ omhttp-batch-jsonarray-vg.sh \
+ omhttp-batch-kafkarest-retry-vg.sh \
+ omhttp-batch-lokirest-retry-vg.sh \
+ omhttp-retry-vg.sh \
+ omhttp-batch-lokirest-vg.sh
+endif
+endif
+
+if ENABLE_OMKAFKA
+if ENABLE_IMKAFKA
+if ENABLE_KAFKA_TESTS
+TESTS += \
+ kafka-selftest.sh \
+ omkafka.sh \
+ omkafkadynakey.sh \
+ imkafka.sh \
+ imkafka-backgrounded.sh \
+ imkafka-config-err-ruleset.sh \
+ imkafka-config-err-param.sh \
+ imkafka-hang-on-no-kafka.sh \
+ imkafka-hang-other-action-on-no-kafka.sh \
+ imkafka_multi_single.sh \
+ imkafka_multi_group.sh \
+ sndrcv_kafka.sh \
+ sndrcv_kafka_multi_topics.sh
+# Tests below need to be stable first!
+# sndrcv_kafka_fail.sh \
+# sndrcv_kafka_failresume.sh \
+# needs properly to much mempory on arm devices!
+# sndrcv_kafka_multi.sh
+omkafka.log: kafka-selftest.log
+imkafka.log: omkafka.log
+imkafka-backgrounded.log: imkafka.log
+imkafka-config-err-ruleset.log: imkafka-backgrounded.log
+imkafka-config-err-param.log: imkafka-config-err-ruleset.log
+imkafka-hang-on-no-kafka.log: imkafka-config-err-param.log
+imkafka-hang-other-action-on-no-kafka.log: imkafka-hang-on-no-kafka.log
+imkafka_multi_single.log: imkafka-hang-other-action-on-no-kafka.log
+sndrcv_kafka.log: imkafka_multi_single.log
+imkafka_multi_group.log: sndrcv_kafka.log
+sndrcv_kafka_multi_topics.log: imkafka_multi_group.log
+omkafkadynakey.log: sndrcv_kafka_multi_topics.log
+
+if HAVE_VALGRIND
+TESTS += \
+ omkafka-vg.sh \
+ imkafka-vg.sh
+
+omkafka-vg.log: sndrcv_kafka_multi_topics.log
+imkafka-vg.log: omkafka-vg.log
+endif
+endif
+endif
+endif
+
+if ENABLE_OMAZUREEVENTHUBS
+if ENABLE_OMAZUREEVENTHUBS_TESTS
+TESTS += \
+ omazureeventhubs-basic.sh \
+ omazureeventhubs-list.sh \
+ omazureeventhubs-stress.sh \
+ omazureeventhubs-interrupt.sh
+if HAVE_VALGRIND
+TESTS += \
+ omazureeventhubs-basic-vg.sh \
+ omazureeventhubs-interrupt-vg.sh
+endif
+endif
+endif
+
+if ENABLE_IMDOCKER
+if ENABLE_IMDOCKER_TESTS
+TESTS += \
+ imdocker-basic.sh \
+ imdocker-long-logline.sh \
+ imdocker-new-logs-from-start.sh \
+ imdocker-multi-line.sh
+if HAVE_VALGRIND
+TESTS += \
+ imdocker-basic-vg.sh \
+ imdocker-long-logline-vg.sh \
+ imdocker-new-logs-from-start-vg.sh \
+ imdocker-multi-line-vg.sh
+endif # HAVE_VALGRIND
+endif # ENABLE_IMDOCKER_TESTS
+endif # ENABLE_IMDOCKER
+
+if ENABLE_IMHTTP
+TESTS += \
+ imhttp-post-payload.sh \
+ imhttp-post-payload-basic-auth.sh \
+ imhttp-post-payload-query-params.sh \
+ imhttp-post-payload-large.sh \
+ imhttp-post-payload-multi.sh \
+ imhttp-post-payload-multi-lf.sh \
+ imhttp-post-payload-compress.sh \
+ imhttp-getrequest-file.sh
+if HAVE_VALGRIND
+TESTS += \
+ imhttp-post-payload-vg.sh \
+ imhttp-post-payload-basic-auth-vg.sh \
+ imhttp-post-payload-query-params-vg.sh \
+ imhttp-post-payload-large-vg.sh \
+ imhttp-post-payload-multi-vg.sh \
+ imhttp-post-payload-multi-lf-vg.sh \
+ imhttp-post-payload-compress-vg.sh \
+ imhttp-getrequest-file-vg.sh
+endif # HAVE_VALGRIND
+endif # ENABLE_IMHTTP
+
+if ENABLE_OMRABBITMQ
+check_PROGRAMS += miniamqpsrvr
+miniamqpsrvr_SOURCES = miniamqpsrvr.c
+miniamqpsrvr_CPPFLAGS = $(PTHREADS_CFLAGS) $(RABBITMQ_CFLAGS) $(RSRT_CFLAGS)
+miniamqpsrvr_LDADD = $(SOL_LIBS) $(PTHREADS_LIBS)
+
+TESTS += \
+ omrabbitmq_no_params.sh \
+ omrabbitmq_params_missing0.sh \
+ omrabbitmq_params_missing1.sh \
+ omrabbitmq_params_missing2.sh \
+ omrabbitmq_params_invalid0.sh \
+ omrabbitmq_params_invalid1.sh \
+ omrabbitmq_params_invalid2.sh \
+ omrabbitmq_params_invalid3.sh \
+ omrabbitmq_data_1server.sh \
+ omrabbitmq_data_2servers.sh \
+ omrabbitmq_error_server0.sh \
+ omrabbitmq_error_server1.sh \
+ omrabbitmq_error_server2.sh \
+ omrabbitmq_error_server3.sh \
+ omrabbitmq_json.sh \
+ omrabbitmq_raw.sh
+if HAVE_VALGRIND
+TESTS += \
+ omrabbitmq_data_1server-vg.sh
+endif # HAVE_VALGRIND
+endif # ENABLE_OMRABBITMQ
+
+if ENABLE_REDIS_TESTS
+if ENABLE_IMHIREDIS
+TESTS += \
+ imhiredis-queue.sh \
+ imhiredis-queue-lpop.sh \
+ imhiredis-redis-restart.sh \
+ imhiredis-redis-start-after.sh \
+ imhiredis-subscribe.sh \
+ imhiredis-stream.sh \
+ imhiredis-stream-from-beginning.sh \
+ imhiredis-stream-consumerGroup-ack.sh \
+ imhiredis-stream-consumerGroup-noack.sh \
+ imhiredis-stream-consumerGroup-reclaim.sh
+if HAVE_VALGRIND
+TESTS += \
+ imhiredis-queue-vg.sh \
+ imhiredis-queue-lpop-vg.sh \
+ imhiredis-redis-restart-vg.sh \
+ imhiredis-redis-start-after-vg.sh \
+ imhiredis-subscribe-vg.sh \
+ imhiredis-stream-vg.sh \
+ imhiredis-stream-from-beginning-vg.sh \
+ imhiredis-stream-consumerGroup-ack-vg.sh \
+ imhiredis-stream-consumerGroup-noack-vg.sh \
+ imhiredis-stream-consumerGroup-reclaim-vg.sh
+endif # HAVE_VALGRIND
+endif # ENABLE_IMHIREDIS
+
+if ENABLE_OMHIREDIS
+TESTS += \
+ mmdb-reload.sh \
+ omhiredis-dynakey.sh \
+ omhiredis-publish.sh \
+ omhiredis-queue-rpush.sh \
+ omhiredis-queue.sh \
+ omhiredis-set.sh \
+ omhiredis-setex.sh \
+ omhiredis-template.sh \
+ omhiredis-withpass.sh \
+ omhiredis-wrongpass.sh \
+ omhiredis-stream-ack.sh \
+ omhiredis-stream-capped.sh \
+ omhiredis-stream-del.sh \
+ omhiredis-stream-dynack.sh \
+ omhiredis-stream-outfield.sh \
+ omhiredis-stream.sh
+if HAVE_VALGRIND
+TESTS += \
+ mmdb-reload-vg.sh \
+ omhiredis-dynakey-vg.sh \
+ omhiredis-publish-vg.sh \
+ omhiredis-queue-rpush-vg.sh \
+ omhiredis-queue-vg.sh \
+ omhiredis-set-vg.sh \
+ omhiredis-setex-vg.sh \
+ omhiredis-template-vg.sh \
+ omhiredis-withpass-vg.sh \
+ omhiredis-wrongpass-vg.sh \
+ omhiredis-stream-ack-vg.sh \
+ omhiredis-stream-capped-vg.sh \
+ omhiredis-stream-del-vg.sh \
+ omhiredis-stream-dynack-vg.sh \
+ omhiredis-stream-outfield-vg.sh \
+ omhiredis-stream-vg.sh
+endif # HAVE_VALGRIND
+endif # ENABLE_OMHIREDIS
+endif # ENABLE_REDIS_TESTS
+
+if ENABLE_IMPSTATS
+TESTS += \
+ impstats-hup.sh \
+ perctile-simple.sh \
+ dynstats.sh \
+ dynstats_overflow.sh \
+ dynstats_reset.sh \
+ dynstats_ctr_reset.sh \
+ dynstats_nometric.sh \
+ no-dynstats-json.sh \
+ no-dynstats.sh \
+ stats-json.sh \
+ dynstats-json.sh \
+ stats-cee.sh \
+ stats-json-es.sh \
+ dynstats_reset_without_pstats_reset.sh \
+ dynstats_prevent_premature_eviction.sh \
+ omfwd_fast_imuxsock.sh \
+ omfwd_impstats-udp.sh \
+ omfwd_impstats-tcp.sh
+if HAVE_VALGRIND
+TESTS += \
+ perctile-simple-vg.sh \
+ dynstats-vg.sh \
+ dynstats_reset-vg.sh \
+ dynstats_overflow-vg.sh \
+ dynstats-json-vg.sh \
+ stats-json-vg.sh \
+ stats-cee-vg.sh \
+ dynstats_prevent_premature_eviction-vg.sh
+endif
+endif
+
+if ENABLE_IMPTCP
+# note that some tests simply USE imptcp, but they also
+# need to be disabled if we do not have this module
+TESTS += \
+ manyptcp.sh \
+ imptcp_framing_regex.sh \
+ imptcp_framing_regex-oversize.sh \
+ imptcp_large.sh \
+ imptcp-connection-msg-disabled.sh \
+ imptcp-connection-msg-received.sh \
+ imptcp-discard-truncated-msg.sh \
+ imptcp_addtlframedelim.sh \
+ imptcp_conndrop.sh \
+ imptcp_no_octet_counted.sh \
+ imptcp_multi_line.sh \
+ imptcp_spframingfix.sh \
+ imptcp_maxsessions.sh \
+ imptcp_nonProcessingPoller.sh \
+ imptcp_veryLargeOctateCountedMessages.sh \
+ imptcp-basic-hup.sh \
+ imptcp-NUL.sh \
+ imptcp-NUL-rawmsg.sh \
+ rscript_random.sh \
+ rscript_hash32.sh \
+ rscript_hash64.sh \
+ rscript_replace.sh \
+ omfile-sizelimitcmd-many.sh \
+ omfile-outchannel-many.sh
+if HAVE_VALGRIND
+TESTS += \
+ imptcp-octet-framing-too-long-vg.sh \
+ imptcp_conndrop-vg.sh
+if ENABLE_FMHASH
+TESTS += \
+ rscript_hash32-vg.sh \
+ rscript_hash64-vg.sh
+endif # ENABLE_FMHASH
+endif # HAVE_VALGRIND
+if ENABLE_FMUNFLATTEN
+TESTS += \
+ rscript_unflatten_arg1_unsuitable.sh \
+ rscript_unflatten_arg2_invalid.sh \
+ rscript_unflatten_conflict1.sh \
+ rscript_unflatten_conflict2.sh \
+ rscript_unflatten_conflict3.sh \
+ rscript_unflatten_key_truncated.sh \
+ rscript_unflatten_non_object.sh \
+ rscript_unflatten_object.sh \
+ rscript_unflatten_object_exclamation.sh
+if HAVE_VALGRIND
+TESTS += \
+ rscript_unflatten_arg1_unsuitable-vg.sh \
+ rscript_unflatten_arg2_invalid-vg.sh \
+ rscript_unflatten_conflict1-vg.sh \
+ rscript_unflatten_conflict2-vg.sh \
+ rscript_unflatten_conflict3-vg.sh \
+ rscript_unflatten_key_truncated-vg.sh \
+ rscript_unflatten_non_object-vg.sh \
+ rscript_unflatten_object-vg.sh \
+ rscript_unflatten_object_exclamation-vg.sh
+endif # HAVE_VALGRIND
+endif # ENABLE_FMUNFLATTEN
+if ENABLE_FFAUP
+TESTS += \
+ rscript_faup_all.sh \
+ rscript_faup_all_2.sh \
+ rscript_faup_all_empty.sh \
+ rscript_faup_scheme.sh \
+ rscript_faup_credential.sh \
+ rscript_faup_subdomain.sh \
+ rscript_faup_domain.sh \
+ rscript_faup_domain_without_tld.sh \
+ rscript_faup_host.sh \
+ rscript_faup_tld.sh \
+ rscript_faup_port.sh \
+ rscript_faup_resource_path.sh \
+ rscript_faup_query_string.sh \
+ rscript_faup_fragment.sh \
+ rscript_faup_mozilla_tld.sh
+if HAVE_VALGRIND
+TESTS += \
+ rscript_faup_all_vg.sh \
+ rscript_faup_all_2_vg.sh \
+ rscript_faup_all_empty_vg.sh \
+ rscript_faup_scheme_vg.sh \
+ rscript_faup_credential_vg.sh \
+ rscript_faup_subdomain_vg.sh \
+ rscript_faup_domain_vg.sh \
+ rscript_faup_domain_without_tld_vg.sh \
+ rscript_faup_host_vg.sh \
+ rscript_faup_tld_vg.sh \
+ rscript_faup_port_vg.sh \
+ rscript_faup_resource_path_vg.sh \
+ rscript_faup_query_string_vg.sh \
+ rscript_faup_fragment_vg.sh \
+ rscript_faup_mozilla_tld_vg.sh
+endif # HAVE_VALGRIND
+endif # ENABLE_FFAUP
+endif
+
+if ENABLE_MMPSTRUCDATA
+TESTS += \
+ mmpstrucdata.sh \
+ mmpstrucdata-escaping.sh \
+ mmpstrucdata-case.sh
+if HAVE_VALGRIND
+TESTS += \
+ mmpstrucdata-vg.sh \
+ mmpstrucdata-invalid-vg.sh
+endif
+endif
+
+if ENABLE_MMRM1STSPACE
+TESTS += \
+ mmrm1stspace-basic.sh
+endif
+
+if ENABLE_PMNULL
+TESTS += \
+ pmnull-basic.sh \
+ pmnull-withparams.sh
+endif
+
+if ENABLE_OMSTDOUT
+TESTS += \
+ omstdout-basic.sh
+endif
+
+if ENABLE_PMNORMALIZE
+TESTS += \
+ pmnormalize-basic.sh \
+ pmnormalize-invld-rulebase.sh \
+ pmnormalize-rule.sh \
+ pmnormalize-rule_and_rulebase.sh \
+ pmnormalize-neither_rule_rulebase.sh \
+ pmnormalize-rule_invld-data.sh
+if HAVE_VALGRIND
+TESTS += \
+ pmnormalize-basic-vg.sh \
+ pmnormalize-invld-rulebase-vg.sh \
+ pmnormalize-rule-vg.sh \
+ pmnormalize-rule_and_rulebase-vg.sh \
+ pmnormalize-neither_rule_rulebase-vg.sh \
+ pmnormalize-rule_invld-data-vg.sh
+endif
+endif
+
+if ENABLE_MMNORMALIZE
+TESTS += msgvar-concurrency-array.sh \
+ msgvar-concurrency-array-event.tags.sh \
+ mmnormalize_rule_from_string.sh \
+ mmnormalize_rule_from_array.sh \
+ mmnormalize_parsesuccess.sh
+
+if HAVE_VALGRIND
+TESTS += \
+ mmnormalize_parsesuccess-vg.sh
+endif
+
+if ENABLE_IMPTCP
+TESTS += \
+ mmnormalize_regex_defaulted.sh \
+ mmnormalize_regex_disabled.sh \
+ mmnormalize_variable.sh \
+ mmnormalize_tokenized.sh
+endif
+
+if LOGNORM_REGEX_SUPPORTED
+TESTS += \
+ mmnormalize_regex.sh
+endif
+endif # ENABLE_MMNORMALIZE
+
+if ENABLE_MMJSONPARSE
+TESTS += \
+ mmjsonparse-w-o-cookie.sh \
+ mmjsonparse-w-o-cookie-multi-spaces.sh
+if ENABLE_IMPSTATS
+TESTS += \
+ mmjsonparse-invalid-containerName.sh \
+ wtpShutdownAll-assertionFailure.sh
+endif
+if ENABLE_IMPTCP
+TESTS += \
+ mmjsonparse_simple.sh \
+ imptcp-oversize-message-display.sh \
+ imptcp-msg-truncation-on-number.sh \
+ imptcp-msg-truncation-on-number2.sh \
+ imptcp-maxFrameSize-parameter.sh \
+ mmjsonparse_cim.sh \
+ mmjsonparse_cim2.sh \
+ mmjsonparse_localvar.sh \
+ json_array_subscripting.sh \
+ json_array_looping.sh \
+ json_object_looping.sh \
+ json_nonarray_looping.sh
+endif
+if HAVE_VALGRIND
+TESTS += \
+ mmjsonparse_extra_data-vg.sh \
+ json_null_array-vg.sh \
+ json_object_looping-vg.sh \
+ json_array_looping-vg.sh \
+ json_object_suicide_in_loop-vg.sh \
+ json_null-vg.sh
+endif
+TESTS += \
+ stop_when_array_has_element.sh \
+ json_null_array.sh \
+ json_null.sh \
+ json_var_cmpr.sh \
+ json_var_case.sh
+endif
+
+if ENABLE_MMDBLOOKUP
+TESTS += \
+ mmdb.sh \
+ mmdb-space.sh \
+ mmdb-container.sh \
+ mmdb-container-empty.sh
+if HAVE_VALGRIND
+TESTS += \
+ mmdb-vg.sh \
+ mmdb-multilevel-vg.sh
+endif
+endif
+
+if ENABLE_GNUTLS_TESTS
+TESTS += \
+ imtcp-tls-basic.sh \
+ imtcp-tls-input-basic.sh \
+ imtcp-tls-input-2certs.sh \
+ imtcp-tls-basic-verifydepth.sh \
+ imtcp_conndrop_tls.sh \
+ sndrcv_tls_anon_rebind.sh \
+ sndrcv_tls_anon_hostname.sh \
+ sndrcv_tls_anon_ipv4.sh \
+ sndrcv_tls_anon_ipv6.sh \
+ sndrcv_tls_certless_clientonly.sh \
+ sndrcv_tls_gtls_servercert_gtls_clientanon.sh \
+ sndrcv_tls_gtls_servercert_gtls_clientanon_legacy.sh \
+ sndrcv_tls_gtls_serveranon_gtls_clientanon.sh \
+ sndrcv_tls_priorityString.sh \
+ sndrcv_tls_certvalid.sh \
+ sndrcv_tls_certvalid_action_level.sh \
+ sndrcv_tls_certvalid_expired.sh \
+ sndrcv_tls_certvalid_expired_defaultmode.sh \
+ sndrcv_tls_certvalid_revoked.sh \
+ sndrcv_tls_client_missing_cert.sh \
+ imtcp-tls-no-lstn-startup.sh \
+ imtcp-tls-gtls-x509fingerprint-invld.sh \
+ imtcp-tls-gtls-x509fingerprint.sh \
+ imtcp-tls-gtls-x509name-invld.sh \
+ imtcp-tls-gtls-x509name.sh \
+ imtcp-tls-gtls-x509name-legacy.sh \
+ imtcp-drvr-in-input-basic.sh \
+ imtcp-multi-drvr-basic.sh \
+ imtcp-multi-drvr-basic-parallel.sh
+if HAVE_VALGRIND
+TESTS += \
+ imtcp-tls-basic-vg.sh \
+ imtcp_conndrop_tls-vg.sh \
+ manytcp-too-few-tls-vg.sh
+endif
+if ENABLE_OPENSSL
+TESTS += \
+ imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh
+endif
+endif
+
+if ENABLE_OPENSSL
+TESTS += \
+ imtcp-tls-ossl-basic.sh \
+ imtcp-tls-ossl-input-basic.sh \
+ imtcp-tls-ossl-input-2certs.sh \
+ imtcp-tls-ossl-basic-tlscommands.sh \
+ imtcp-tls-ossl-basic-verifydepth.sh \
+ imtcp-tls-ossl-invalid-verifydepth.sh \
+ sndrcv_tls_ossl_anon_ipv4.sh \
+ sndrcv_tls_ossl_anon_ipv6.sh \
+ sndrcv_tls_ossl_anon_rebind.sh \
+ sndrcv_tls_ossl_anon_ciphers.sh \
+ sndrcv_tls_ossl_serveranon_ossl_clientanon.sh \
+ sndrcv_tls_ossl_servercert_ossl_clientanon.sh \
+ sndrcv_tls_ossl_certvalid.sh \
+ sndrcv_tls_ossl_certvalid_action_level.sh \
+ sndrcv_tls_ossl_certvalid_expired.sh \
+ sndrcv_tls_ossl_certvalid_tlscommand.sh \
+ sndrcv_tls_ossl_certvalid_ciphers.sh \
+ sndrcv_tls_ossl_certvalid_revoked.sh \
+ imtcp-tls-ossl-x509valid.sh \
+ imtcp-tls-ossl-x509name.sh \
+ imtcp-tls-ossl-x509fingerprint.sh \
+ imtcp-tls-ossl-error-ca.sh \
+ imtcp-tls-ossl-error-cert.sh \
+ imtcp-tls-ossl-error-key.sh \
+ imtcp-tls-ossl-error-key2.sh
+if HAVE_VALGRIND
+TESTS += \
+ imtcp-tls-ossl-basic-vg.sh \
+ imtcp-tls-ossl-basic-brokenhandshake-vg.sh
+endif
+endif
+
+if ENABLE_GNUTLS_TESTS
+if ENABLE_OPENSSL
+TESTS += \
+ sndrcv_tls_ossl_servercert_gtls_clientanon.sh \
+ sndrcv_tls_ossl_serveranon_gtls_clientanon.sh \
+ sndrcv_tls_gtls_servercert_ossl_clientanon.sh \
+ sndrcv_tls_gtls_serveranon_ossl_clientanon.sh
+endif
+endif
+
+if ENABLE_OMUXSOCK
+TESTS += uxsock_simple.sh
+endif
+
+if ENABLE_RELP
+TESTS += sndrcv_relp.sh \
+ sndrcv_relp_rebind.sh \
+ omrelp_errmsg_no_connect.sh \
+ imrelp-basic.sh \
+ imrelp-basic-oldstyle.sh \
+ imrelp-basic-hup.sh \
+ imrelp-manyconn.sh \
+ imrelp-maxDataSize-error.sh \
+ imrelp-long-msg.sh \
+ imrelp-oversizeMode-truncate.sh \
+ imrelp-oversizeMode-accept.sh \
+ imrelp-invld-tlslib.sh \
+ imrelp-bigmessage.sh \
+ omrelp-invld-tlslib.sh \
+ sndrcv_relp_dflt_pt.sh \
+ glbl-oversizeMsg-log.sh \
+ glbl-oversizeMsg-truncate.sh \
+ glbl-oversizeMsg-split.sh
+if ENABLE_GNUTLS
+TESTS += \
+ sndrcv_relp_tls.sh \
+ sndrcv_relp_tls_certvalid.sh \
+ sndrcv_tls_certvalid_action_level.sh \
+ sndrcv_relp_tls_prio.sh \
+ sndrcv_relp_tls_chainedcert.sh \
+ relp_tls_certificate_not_found.sh \
+ omrelp_wrong_authmode.sh \
+ imrelp-tls.sh \
+ imrelp-tls-chainedcert.sh \
+ imrelp-tls-mixed-chainedcert.sh \
+ imrelp-tls-mixed-chainedcert2.sh
+if USE_RELPENGINESETTLSCFGCMD
+TESTS += \
+ imrelp-tls-cfgcmd.sh \
+ sndrcv_relp_tls-cfgcmd.sh
+endif # USE_RELPENGINESETTLSCFGCMD
+endif # ENABLE_GNUTLS
+if HAVE_VALGRIND
+TESTS += \
+ imrelp-basic-vg.sh \
+ imrelp-sessionbreak-vg.sh \
+ imrelp-manyconn-vg.sh \
+ sndrcv_relp-vg-rcvr.sh \
+ sndrcv_relp-vg-sender.sh
+endif # HAVE_VALGRIND
+endif
+
+if ENABLE_IMDTLS
+TESTS += \
+ imdtls-basic.sh \
+ imdtls-basic-tlscommands.sh \
+ imdtls-basic-timeout.sh \
+ imdtls-error-cert.sh \
+ imdtls-sessionbreak.sh
+if HAVE_VALGRIND
+TESTS += \
+ imdtls-basic-vg.sh \
+ imdtls-sessionbreak-vg.sh
+endif # HAVE_VALGRIND
+if ENABLE_OMDTLS
+TESTS += \
+ sndrcv_dtls_certvalid.sh \
+ sndrcv_dtls_anon_ciphers.sh \
+ sndrcv_dtls_certvalid_ciphers.sh \
+ sndrcv_dtls_certvalid_permitted.sh \
+ sndrcv_dtls_certvalid_missing.sh \
+ sndrcv_dtls_anon_ciphers.sh
+if HAVE_VALGRIND
+TESTS += \
+ sndrcv_dtls_certvalid-vg.sh
+endif # HAVE_VALGRIND
+endif # ENABLE_OMDTLS
+endif # ENABLE_IMDTLS
+
+if ENABLE_OMUDPSPOOF
+TESTS += \
+ omudpspoof_errmsg_no_params.sh \
+ sndrcv_omudpspoof.sh \
+ sndrcv_omudpspoof-bigmsg.sh \
+ sndrcv_omudpspoof_nonstdpt.sh
+endif
+
+#disabled as array-passing mode is no longer supported: omod-if-array.sh
+# omod-if-array.sh
+# omod-if-array-udp.sh
+if ENABLE_IMPTCP
+TESTS += \
+ tabescape_dflt.sh \
+ tabescape_dflt-udp.sh \
+ tabescape_off.sh \
+ tabescape_off-udp.sh \
+ tabescape_on.sh \
+ inputname-imtcp.sh \
+ fieldtest.sh \
+ fieldtest-udp.sh \
+ proprepltest-nolimittag-udp.sh \
+ proprepltest-nolimittag.sh \
+ proprepltest-rfctag-udp.sh \
+ proprepltest-rfctag.sh
+
+endif
+
+if ENABLE_OMRULESET
+TESTS += \
+ omruleset.sh \
+ omruleset-queue.sh
+endif
+
+if ENABLE_PMDB2DIAG
+TESTS += \
+ pmdb2diag_parse.sh
+endif
+
+if ENABLE_PMSNARE
+TESTS += \
+ pmsnare-default.sh \
+ pmsnare-default-udp.sh \
+ pmsnare-ccoff.sh \
+ pmsnare-ccoff-udp.sh \
+ pmsnare-ccdefault.sh \
+ pmsnare-ccdefault-udp.sh \
+ pmsnare-cccstyle.sh \
+ pmsnare-cccstyle-udp.sh \
+ pmsnare-ccbackslash.sh \
+ pmsnare-ccbackslash-udp.sh \
+ pmsnare-modoverride.sh \
+ pmsnare-modoverride-udp.sh
+endif
+
+if ENABLE_PMLASTMSG
+TESTS += \
+ pmlastmsg.sh \
+ pmlastmsg-udp.sh
+endif
+
+if ENABLE_EXTENDED_TESTS
+# random.sh is temporarily disabled as it needs some work
+# to rsyslog core to complete in reasonable time
+#TESTS += random.sh
+if ENABLE_IMFILE_TESTS
+TESTS += \
+ imfile-basic-2GB-file.sh \
+ imfile-truncate-2GB-file.sh
+endif # ENABLE_IMFILE_TESTS
+endif
+
+if ENABLE_IMFILE_TESTS
+TESTS += \
+ imfile-basic.sh \
+ imfile-basic-legacy.sh \
+ imfile-discard-truncated-line.sh \
+ imfile-truncate-line.sh \
+ imfile-file-not-found-error.sh \
+ imfile-fileNotFoundError-parameter.sh \
+ imfile-error-not-repeated.sh \
+ imfile-truncate.sh \
+ imfile-truncate-multiple.sh \
+ imfile-readmode2.sh \
+ imfile-readmode2-polling.sh \
+ imfile-readmode2-with-persists-data-during-stop.sh \
+ imfile-readmode2-with-persists.sh \
+ imfile-endregex.sh \
+ imfile-endregex-save-lf.sh \
+ imfile-endregex-save-lf-persist.sh \
+ imfile-endregex-timeout-none-polling.sh \
+ imfile-endregex-timeout-polling.sh \
+ imfile-endregex-timeout.sh \
+ imfile-endregex-timeout-none.sh \
+ imfile-endregex-timeout-with-shutdown.sh \
+ imfile-endregex-timeout-with-shutdown-polling.sh \
+ imfile-endmsg.regex.sh \
+ imfile-escapelf.replacement.sh \
+ imfile-escapelf.replacement-empty.sh \
+ imfile-statefile-no-file_id.sh \
+ imfile-statefile-no-file_id-TO-file_id.sh \
+ imfile-statefile-directory.sh \
+ imfile-statefile-delete.sh \
+ imfile-statefile-no-delete.sh \
+ imfile-persist-state-1.sh \
+ imfile-freshStartTail1.sh \
+ imfile-freshStartTail2.sh \
+ imfile-freshStartTail3.sh \
+ imfile-wildcards.sh \
+ imfile-wildcards-dirs.sh \
+ imfile-wildcards-dirs2.sh \
+ imfile-wildcards-dirs-multi.sh \
+ imfile-wildcards-dirs-multi2.sh \
+ imfile-wildcards-dirs-multi3.sh \
+ imfile-wildcards-dirs-multi4.sh \
+ imfile-wildcards-dirs-multi5.sh \
+ imfile-wildcards-dirs-multi5-polling.sh \
+ imfile-old-state-file.sh \
+ imfile-rename-while-stopped.sh \
+ imfile-rename.sh \
+ imfile-symlink.sh \
+ imfile-symlink-multi.sh \
+ imfile-symlink-ext-tmp-dir-tree.sh \
+ imfile-logrotate.sh \
+ imfile-logrotate-async.sh \
+ imfile-logrotate-multiple.sh \
+ imfile-logrotate-copytruncate.sh \
+ imfile-logrotate-nocopytruncate.sh \
+ imfile-growing-file-id.sh \
+ imfile-ignore-old-file-1.sh \
+ imfile-ignore-old-file-2.sh \
+ imfile-ignore-old-file-3.sh \
+ imfile-ignore-old-file-4.sh \
+ imfile-ignore-old-file-5.sh \
+ imfile-ignore-old-file-6.sh \
+ imfile-ignore-old-file-7.sh \
+ glbl-oversizeMsg-truncate-imfile.sh \
+ config_enabled-on.sh \
+ config_enabled-off.sh
+
+if ENABLE_MMNORMALIZE
+TESTS += \
+ imfile-endmsg.regex-with-example.sh
+endif
+
+if HAVE_VALGRIND
+TESTS += \
+ imfile-basic-vg.sh \
+ imfile-endregex-vg.sh \
+ imfile-endmsg.regex-vg.sh \
+ imfile-readmode0-vg.sh \
+ imfile-readmode2-vg.sh
+
+if ENABLE_HELGRIND
+TESTS += \
+ imfile-basic-vgthread.sh
+endif # ENABLE_HELGRIND
+
+if ENABLE_MMNORMALIZE
+TESTS += \
+ imfile-endmsg.regex-with-example-vg.sh
+endif # ENABLE_MMNORMALIZE
+
+endif # HAVE_VALGRIND
+
+endif # ENABLE_IMFILE_TESTS
+
+if ENABLE_IMBATCHREPORT
+TESTS += \
+ imbatchreport_errmsg_no_params.sh \
+ imbatchreport_errmsg_glob_not_regular.sh \
+ imbatchreport_errmsg_glob_dir_fake.sh \
+ imbatchreport_errmsg_glob_dir_not_dir.sh \
+ imbatchreport_errmsg_regex.match.reject.sh \
+ imbatchreport_errmsg_regex.match.rename.sh \
+ imbatchreport_errmsg_regex.nomatch.sh \
+ imbatchreport_errmsg_not_supported1.sh \
+ imbatchreport_errmsg_not_supported2.sh \
+ imbatchreport_errmsg_not_supported3.sh \
+ imbatchreport_errmsg_delete_params.sh \
+ imbatchreport_errmsg_rename_params.sh \
+ imbatchreport_delete_success.sh \
+ imbatchreport_delete_structdata.sh \
+ imbatchreport_rename_success.sh \
+ imbatchreport_delete_toolarge.sh \
+ imbatchreport_rename_toolarge.sh
+if HAVE_VALGRIND
+TESTS += \
+ imbatchreport_errmsg_no_params-vg.sh
+endif # ENABLE_IMBATCHREPORT
+endif
+
+if ENABLE_OMTCL
+TESTS += \
+ omtcl.sh
+endif
+
+if ENABLE_MMTAGHOSTNAME
+TESTS += \
+ mmtaghostname_tag.sh \
+ mmtaghostname_server.sh
+endif
+
+if ENABLE_MMKUBERNETES
+if ENABLE_MMJSONPARSE
+if ENABLE_IMFILE
+if ENABLE_IMPSTATS
+TESTS += \
+ mmkubernetes-basic.sh \
+ mmkubernetes-cache-expire.sh
+if HAVE_VALGRIND
+TESTS += \
+ mmkubernetes-basic-vg.sh \
+ mmkubernetes-cache-expire-vg.sh
+endif
+endif
+endif
+endif
+endif
+
+if ENABLE_IMTUXEDOULOG
+TESTS += \
+ imtuxedoulog_errmsg_no_params.sh \
+ imtuxedoulog_data.sh
+if HAVE_VALGRIND
+TESTS += \
+ imtuxedoulog_errmsg_no_params-vg.sh
+endif # ENABLE_IMTUXEDOULOG
+endif
+
+if ENABLE_OMAMQP1
+TESTS += \
+ omamqp1-basic.sh
+if HAVE_VALGRIND
+TESTS += \
+ omamqp1-basic-vg.sh
+endif
+endif # ENABLE_OMAMQP1
+
+endif # if ENABLE_TESTBENCH
+
+TESTS_ENVIRONMENT = RSYSLOG_MODDIR='$(abs_top_builddir)'/runtime/.libs/
+TESTS_ENVIRONMENT+= TOP_BUILDDIR='$(top_builddir)'
+TESTS_ENVIRONMENT+= TESTTOOL_DIR='$(abs_top_builddir)/tests'
+test_files = testbench.h runtime-dummy.c
+DISTCLEANFILES=rsyslog.pid
+
+distclean-local:
+ rm -rf .dep_cache .dep_wrk
+
+EXTRA_DIST= \
+ set-envvars.in \
+ urlencode.py \
+ dnscache-TTL-0.sh \
+ dnscache-TTL-0-vg.sh \
+ loadbalance.sh \
+ smtradfile.sh \
+ smtradfile-vg.sh \
+ immark.sh \
+ immark-inputname.sh \
+ immark-ruleset.sh \
+ immark-ruleset-custom-msg.sh \
+ operatingstate-basic.sh \
+ operatingstate-empty.sh \
+ operatingstate-unclean.sh \
+ internal-errmsg-memleak-vg.sh \
+ glbl-ruleset-queue-defaults.sh \
+ glbl-internalmsg_severity-info-shown.sh \
+ glbl-internalmsg_severity-debug-shown.sh \
+ glbl-internalmsg_severity-debug-not_shown.sh \
+ glbl-oversizeMsg-log-vg.sh \
+ config_enabled-on.sh \
+ config_enabled-off.sh \
+ empty-app-name.sh \
+ empty-hostname.sh \
+ func-substring-invld-startpos.sh \
+ func-substring-invld-startpos-vg.sh \
+ func-substring-large-endpos.sh \
+ func-substring-large-neg-endpos.sh \
+ func-substring-relative-endpos.sh \
+ hostname-with-slash-pmrfc5424.sh \
+ hostname-with-slash-pmrfc3164.sh \
+ pmrfc3164-msgFirstSpace.sh \
+ pmrfc3164-AtSignsInHostname.sh \
+ pmrfc3164-AtSignsInHostname_off.sh \
+ pmrfc3164-tagEndingByColon.sh \
+ pmrfc3164-defaultTag.sh \
+ pmrfc3164-json.sh \
+ hostname-with-slash-dflt-invld.sh \
+ hostname-with-slash-dflt-slash-valid.sh \
+ glbl-umask.sh \
+ glbl-unloadmodules.sh \
+ glbl-invld-param.sh \
+ glbl_setenv_2_vars.sh \
+ glbl_setenv_err.sh \
+ glbl_setenv_err_too_long.sh \
+ glbl_setenv.sh \
+ imtuxedoulog_errmsg_no_params.sh \
+ imtuxedoulog_data.sh \
+ imtuxedoulog_errmsg_no_params-vg.sh \
+ pmdb2diag_parse.sh \
+ mmtaghostname_tag.sh \
+ mmtaghostname_server.sh \
+ imbatchreport_errmsg_no_params.sh \
+ imbatchreport_errmsg_glob_not_regular.sh \
+ imbatchreport_errmsg_glob_dir_fake.sh \
+ imbatchreport_errmsg_glob_dir_not_dir.sh \
+ imbatchreport_errmsg_regex.match.reject.sh \
+ imbatchreport_errmsg_regex.match.rename.sh \
+ imbatchreport_errmsg_regex.nomatch.sh \
+ imbatchreport_errmsg_not_supported1.sh \
+ imbatchreport_errmsg_not_supported2.sh \
+ imbatchreport_errmsg_not_supported3.sh \
+ imbatchreport_errmsg_delete_params.sh \
+ imbatchreport_errmsg_rename_params.sh \
+ imbatchreport_delete_success.sh \
+ imbatchreport_delete_structdata.sh \
+ imbatchreport_rename_success.sh \
+ imbatchreport_delete_toolarge.sh \
+ imbatchreport_rename_toolarge.sh \
+ imbatchreport_errmsg_no_params-vg.sh \
+ mmexternal-SegFault.sh \
+ mmexternal-SegFault-empty-jroot-vg.sh \
+ testsuites/mmexternal-SegFault-mm-python.py \
+ mmexternal-InvldProg-vg.sh \
+ nested-call-shutdown.sh \
+ 1.rstest 2.rstest 3.rstest err1.rstest \
+ config_multiple_include.sh \
+ testsuites/include-std1-omfile-action.conf \
+ testsuites/include-std2-omfile-action.conf \
+ invalid_nested_include.sh \
+ validation-run.sh \
+ tls-certs/ca-key.pem \
+ tls-certs/ca.pem \
+ tls-certs/cert.pem \
+ tls-certs/certchained.pem \
+ tls-certs/key.pem \
+ tls-certs/ca-fail.pem \
+ tls-certs/cert-fail.pem \
+ tls-certs/key-fail.pem \
+ testsuites/x.509/ca.srl \
+ testsuites/x.509/client-cert-new.pem \
+ testsuites/x.509/client-new.csr \
+ testsuites/x.509/client-revoked-key.pem \
+ testsuites/x.509/client-revoked-valid.pem \
+ testsuites/x.509/client-revoked.csr \
+ testsuites/x.509/client-revoked.pem \
+ testsuites/x.509/crl.pem \
+ testsuites/x.509/index.txt \
+ testsuites/x.509/index.txt.attr \
+ testsuites/x.509/newcerts/01.pem \
+ testsuites/x.509/newcerts/02.pem \
+ testsuites/x.509/newcerts/03.pem \
+ testsuites/x.509/newcerts/04.pem \
+ testsuites/x.509/openssl-cmds.sh \
+ testsuites/x.509/openssl.cnf \
+ testsuites/x.509/serial \
+ testsuites/x.509/ca.pem \
+ testsuites/x.509/ca-key.pem \
+ testsuites/x.509/client-cert.pem \
+ testsuites/x.509/client-key.pem \
+ testsuites/x.509/machine-cert.pem \
+ testsuites/x.509/machine-key.pem \
+ testsuites/x.509/client-expired-cert.pem \
+ testsuites/x.509/client-expired-key.pem \
+ cfg.sh \
+ cfg1.cfgtest \
+ cfg1.testin \
+ cfg2.cfgtest \
+ cfg2.testin \
+ cfg3.cfgtest \
+ cfg3.testin \
+ cfg4.cfgtest \
+ cfg4.testin \
+ DevNull.cfgtest \
+ err1.rstest \
+ NoExistFile.cfgtest \
+ tcp_forwarding_tpl.sh \
+ tcp_forwarding_ns_tpl.sh \
+ tcp_forwarding_dflt_tpl.sh \
+ tcp_forwarding_retries.sh \
+ mainq_actq_DA.sh \
+ queue_warnmsg-oversize.sh \
+ queue-minbatch.sh \
+ queue-minbatch-queuefull.sh \
+ queue-direct-with-no-params.sh \
+ queue-direct-with-params-given.sh \
+ killrsyslog.sh \
+ parsertest-parse1.sh \
+ parsertest-parse1-udp.sh \
+ parsertest-parse2.sh \
+ parsertest-parse2-udp.sh \
+ parsertest-parse_8bit_escape.sh \
+ parsertest-parse_8bit_escape-udp.sh \
+ parsertest-parse3.sh \
+ parsertest-parse3-udp.sh \
+ parsertest-parse_invld_regex.sh \
+ parsertest-parse_invld_regex-udp.sh \
+ parsertest-parse-3164-buggyday.sh \
+ parsertest-parse-3164-buggyday-udp.sh \
+ parsertest-parse-nodate.sh \
+ parsertest-parse-nodate-udp.sh \
+ parsertest-snare_ccoff_udp.sh \
+ parsertest-snare_ccoff_udp2.sh \
+ fieldtest.sh \
+ fieldtest-udp.sh \
+ proprepltest-nolimittag-udp.sh \
+ proprepltest-nolimittag.sh \
+ proprepltest-rfctag-udp.sh \
+ proprepltest-rfctag.sh \
+ timestamp-3164.sh \
+ timestamp-3339.sh \
+ timestamp-isoweek.sh \
+ timestamp-mysql.sh \
+ timestamp-pgsql.sh \
+ timestamp-subseconds.sh \
+ rsf_getenv.sh \
+ diskq-rfc5424.sh \
+ rfc5424parser-sp_at_msg_start.sh \
+ diskqueue-full.sh \
+ diskqueue-fail.sh \
+ diskqueue.sh \
+ diskqueue-non-unique-prefix.sh \
+ arrayqueue.sh \
+ include-obj-text-from-file.sh \
+ include-obj-text-from-file-noexist.sh \
+ include-obj-outside-control-flow-vg.sh \
+ include-obj-in-if-vg.sh \
+ include-obj-text-vg.sh \
+ config_output-o-option.sh \
+ rscript-config_enable-off-vg.sh \
+ rscript-config_enable-on.sh \
+ rscript_http_request.sh \
+ rscript_http_request-vg.sh \
+ rscript_bare_var_root.sh \
+ rscript_bare_var_root-empty.sh \
+ rscript_contains.sh \
+ rscript_ipv42num.sh \
+ rscript_field.sh \
+ rscript_field-vg.sh \
+ rscript_stop.sh \
+ rscript_stop2.sh \
+ stop.sh \
+ rscript_le.sh \
+ rscript_le_var.sh \
+ rscript_ge.sh \
+ rscript_ge_var.sh \
+ rscript_lt.sh \
+ rscript_lt_var.sh \
+ rscript_gt.sh \
+ rscript_gt_var.sh \
+ rscript_ne.sh \
+ rscript_ne_var.sh \
+ rscript_number_comparison_LE.sh \
+ rscript_number_comparison_LE-vg.sh \
+ rscript_number_comparison_LT.sh \
+ rscript_compare_str-numstr.sh \
+ rscript_compare_str-num.sh \
+ rscript_compare_numstr-str.sh \
+ rscript_compare_num-str.sh \
+ rscript_compare_numstr-numstr.sh \
+ rscript_compare_numstr-num.sh \
+ rscript_compare_num-numstr.sh \
+ rscript_compare_num-num.sh \
+ rscript_compare_str-str.sh \
+ rscript_compare_str-str-vg.sh \
+ rscript_compare_str-num-vg.sh \
+ rscript_compare_str-numstr-vg.sh \
+ rscript_compare_num-str-vg.sh \
+ rscript_compare_numstr-str-vg.sh \
+ rscript_compare_numstr-num-vg.sh \
+ rscript_compare_numstr-numstr-vg.sh \
+ rscript_compare_num-num-vg.sh \
+ rscript_compare_num-numstr-vg.sh \
+ rscript_compare-common.sh \
+ rscript_num2ipv4.sh \
+ rscript_int2Hex.sh \
+ rscript_trim.sh \
+ rscript_substring.sh \
+ rscript_format_time.sh \
+ rscript_parse_time.sh \
+ rscript_parse_time_get-ts.py \
+ rscript_is_time.sh \
+ rscript_script_error.sh \
+ rscript_parse_json.sh \
+ rscript_parse_json-vg.sh \
+ rscript_backticks-vg.sh \
+ rscript_backticks_empty_envvar-vg.sh \
+ rscript_previous_action_suspended.sh \
+ rscript_str2num_negative.sh \
+ rscript_exists-yes.sh \
+ rscript_exists-yes2.sh \
+ rscript_exists-not1.sh \
+ rscript_exists-not2.sh \
+ rscript_exists-not3.sh \
+ rscript_exists-not4.sh \
+ rscript_unflatten_arg1_unsuitable.sh \
+ rscript_unflatten_arg2_invalid.sh \
+ rscript_unflatten_conflict1.sh \
+ rscript_unflatten_conflict2.sh \
+ rscript_unflatten_conflict3.sh \
+ rscript_unflatten_key_truncated.sh \
+ rscript_unflatten_non_object.sh \
+ rscript_unflatten_object_exclamation.sh \
+ rscript_unflatten_object.sh \
+ rscript_unflatten_arg1_unsuitable-vg.sh \
+ rscript_unflatten_arg2_invalid-vg.sh \
+ rscript_unflatten_conflict1-vg.sh \
+ rscript_unflatten_conflict2-vg.sh \
+ rscript_unflatten_conflict3-vg.sh \
+ rscript_unflatten_key_truncated-vg.sh \
+ rscript_unflatten_non_object-vg.sh \
+ rscript_unflatten_object_exclamation-vg.sh \
+ rscript_unflatten_object-vg.sh \
+ rscript_get_property.sh \
+ rscript_get_property-vg.sh \
+ rs-cnum.sh \
+ rs-int2hex.sh \
+ rs-substring.sh \
+ omsnmp_errmsg_no_params.sh \
+ sndrcv_omsnmpv1_udp.sh \
+ sndrcv_omsnmpv1_udp_dynsource.sh \
+ sndrcv_omsnmpv1_udp_invalidoid.sh \
+ snmptrapreceiver.py \
+ ommail_errmsg_no_params.sh \
+ mmdarwin_errmsg_no_params.sh \
+ mmdarwin_errmsg_no_sock.sh \
+ mmdarwin_errmsg_no_sock-vg.sh \
+ mmutf8fix_no_error.sh \
+ tcpflood_wrong_option_output.sh \
+ msleep_usage_output.sh \
+ mangle_qi_usage_output.sh \
+ minitcpsrv_usage_output.sh \
+ test_id_usage_output.sh \
+ mmanon_with_debug.sh \
+ mmanon_random_32_ipv4.sh \
+ mmanon_random_cons_32_ipv4.sh \
+ mmanon_recognize_ipv4.sh \
+ mmanon_zero_12_ipv4.sh \
+ mmanon_zero_33_ipv4.sh \
+ mmanon_zero_8_ipv4.sh \
+ mmanon_simple_12_ipv4.sh \
+ mmanon_simple_33_ipv4.sh \
+ mmanon_simple_8_ipv4.sh \
+ mmanon_simple_mallformed_ipv4.sh \
+ mmanon_random_128_ipv6.sh \
+ mmanon_zero_128_ipv6.sh \
+ mmanon_zero_96_ipv6.sh \
+ mmanon_random_cons_128_ipv6.sh \
+ mmanon_zero_50_ipv6.sh \
+ mmanon_recognize_ipv6.sh \
+ mmanon_zero_64_ipv6.sh \
+ mmanon_both_modes_compatible.sh \
+ mmanon_recognize_ipembedded.sh \
+ mmanon_ipv6_port.sh \
+ mmanon_random_cons_128_ipembedded.sh \
+ rscript_eq.sh \
+ rscript_eq_var.sh \
+ rscript_set_memleak-vg.sh \
+ rscript_set_unset_invalid_var.sh \
+ rscript_set_modify.sh \
+ stop-localvar.sh \
+ stop-msgvar.sh \
+ omfwd-tls-invalid-permitExpiredCerts.sh \
+ omfwd-keepalive.sh \
+ omfwd_fast_imuxsock.sh \
+ omfile_hup-vg.sh \
+ zstd.sh \
+ zstd-vg.sh \
+ gzipwr_hup-vg.sh \
+ omusrmsg-errmsg-no-params.sh \
+ omusrmsg-noabort.sh \
+ omusrmsg-noabort-vg.sh \
+ omfile-module-params.sh \
+ omfile-read-only-errmsg.sh \
+ omfile-null-filename.sh \
+ omfile-whitespace-filename.sh \
+ omfile-read-only.sh \
+ omfile-outchannel.sh \
+ omfile-outchannel-many.sh \
+ omfile-sizelimitcmd-many.sh \
+ omfile_both_files_set.sh \
+ omfile_hup.sh \
+ omrabbitmq_no_params.sh \
+ omrabbitmq_params_missing0.sh \
+ omrabbitmq_params_missing1.sh \
+ omrabbitmq_params_missing2.sh \
+ omrabbitmq_params_invalid0.sh \
+ omrabbitmq_params_invalid1.sh \
+ omrabbitmq_params_invalid2.sh \
+ omrabbitmq_params_invalid3.sh \
+ omrabbitmq_data_1server.sh \
+ omrabbitmq_data_1server-vg.sh \
+ omrabbitmq_data_2servers.sh \
+ omrabbitmq_error_server0.sh \
+ omrabbitmq_error_server1.sh \
+ omrabbitmq_error_server2.sh \
+ omrabbitmq_error_server3.sh \
+ omrabbitmq_json.sh \
+ omrabbitmq_raw.sh \
+ imhiredis-queue.sh \
+ imhiredis-queue-vg.sh \
+ imhiredis-queue-lpop.sh \
+ imhiredis-queue-lpop-vg.sh \
+ imhiredis-redis-restart.sh \
+ imhiredis-redis-restart-vg.sh \
+ imhiredis-redis-start-after.sh \
+ imhiredis-redis-start-after-vg.sh \
+ imhiredis-subscribe.sh \
+ imhiredis-subscribe-vg.sh \
+ imhiredis-stream.sh \
+ imhiredis-stream-vg.sh \
+ imhiredis-stream-from-beginning.sh \
+ imhiredis-stream-from-beginning-vg.sh \
+ imhiredis-stream-consumerGroup-ack.sh \
+ imhiredis-stream-consumerGroup-ack-vg.sh \
+ imhiredis-stream-consumerGroup-noack.sh \
+ imhiredis-stream-consumerGroup-noack-vg.sh \
+ imhiredis-stream-consumerGroup-reclaim.sh \
+ imhiredis-stream-consumerGroup-reclaim-vg.sh \
+ msgvar-concurrency.sh \
+ msgvar-concurrency-array.sh \
+ testsuites/msgvar-concurrency-array.rulebase \
+ msgvar-concurrency-array-event.tags.sh \
+ testsuites/msgvar-concurrency-array-event.tags.rulebase \
+ localvar-concurrency.sh \
+ exec_tpl-concurrency.sh \
+ prop-jsonmesg-vg.sh \
+ prop-all-json-concurrency.sh \
+ no-parser-errmsg.sh \
+ global_vars.sh \
+ no-parser-errmsg.sh \
+ no-parser-vg.sh \
+ prop-programname.sh \
+ prop-programname-with-slashes.sh \
+ rfc5424parser.sh \
+ rscript_privdropuser.sh \
+ rscript_privdropuserid.sh \
+ rscript_privdropgroup.sh \
+ rscript_privdropgroupid.sh \
+ privdrop_common.sh \
+ privdropuser.sh \
+ privdropuserid.sh \
+ privdropgroup.sh \
+ privdropgroupid.sh \
+ privdropabortonidfail.sh \
+ privdropabortonidfaillegacy.sh \
+ json-nonstring.sh \
+ json-onempty-at-end.sh \
+ template-json.sh \
+ template-pure-json.sh \
+ template-pos-from-to.sh \
+ template-pos-from-to-lowercase.sh \
+ template-pos-from-to-oversize.sh \
+ template-pos-from-to-oversize-lowercase.sh \
+ template-pos-from-to-missing-jsonvar.sh \
+ template-const-jsonf.sh \
+ template-topos-neg.sh \
+ fac_authpriv.sh \
+ fac_local0.sh \
+ fac_local0-vg.sh \
+ fac_local7.sh \
+ fac_mail.sh \
+ fac_news.sh \
+ fac_ftp.sh \
+ fac_ntp.sh \
+ fac_uucp.sh \
+ fac_invld1.sh \
+ fac_invld2.sh \
+ fac_invld3.sh \
+ fac_invld4_rfc5424.sh \
+ compresssp.sh \
+ compresssp-stringtpl.sh \
+ now_family_utc.sh \
+ now-utc-ymd.sh \
+ now-utc-casecmp.sh \
+ now-utc.sh \
+ now-unixtimestamp.sh \
+ faketime_common.sh \
+ imjournal-basic.sh \
+ imjournal-statefile.sh \
+ imjournal-statefile-vg.sh \
+ imjournal-basic-vg.sh \
+ omjournal-abort-template.sh \
+ omjournal-abort-no-template.sh \
+ omjournal-basic-template.sh \
+ omjournal-basic-no-template.sh \
+ timegenerated-ymd.sh \
+ timegenerated-uxtimestamp.sh \
+ timegenerated-uxtimestamp-invld.sh \
+ timegenerated-dateordinal.sh \
+ timegenerated-dateordinal-invld.sh \
+ timegenerated-utc.sh \
+ timegenerated-utc-legacy.sh \
+ timereported-utc.sh \
+ timereported-utc-legacy.sh \
+ timereported-utc-vg.sh \
+ mmrm1stspace-basic.sh \
+ mmnormalize_parsesuccess.sh \
+ mmnormalize_parsesuccess-vg.sh \
+ mmnormalize_rule_from_string.sh \
+ mmnormalize_rule_from_array.sh \
+ pmnull-basic.sh \
+ pmnull-withparams.sh \
+ omstdout-basic.sh \
+ testsuites/mmnormalize_processing_tests.rulebase \
+ mmnormalize_processing_test1.sh \
+ mmnormalize_processing_test2.sh \
+ mmnormalize_processing_test3.sh \
+ mmnormalize_processing_test4.sh \
+ pmnormalize-basic.sh \
+ pmnormalize-rule.sh \
+ pmnormalize-rule_and_rulebase.sh \
+ pmnormalize-neither_rule_rulebase.sh \
+ pmnormalize-invld-rulebase.sh \
+ pmnormalize-rule_invld-data.sh \
+ testsuites/pmnormalize_basic.rulebase \
+ pmnormalize-basic-vg.sh \
+ pmnormalize-rule-vg.sh\
+ pmnormalize-rule_and_rulebase-vg.sh \
+ pmnormalize-neither_rule_rulebase-vg.sh \
+ pmnormalize-invld-rulebase-vg.sh \
+ pmnormalize-rule_invld-data-vg.sh \
+ rawmsg-after-pri.sh \
+ rs_optimizer_pri.sh \
+ rscript_prifilt.sh \
+ rscript_optimizer1.sh \
+ rscript_ruleset_call.sh \
+ rscript_ruleset_call_indirect-basic.sh \
+ rscript_ruleset_call_indirect-var.sh \
+ rscript_ruleset_call_indirect-invld.sh \
+ cee_simple.sh \
+ cee_diskqueue.sh \
+ mmjsonparse-w-o-cookie.sh \
+ mmjsonparse-w-o-cookie-multi-spaces.sh \
+ mmjsonparse_simple.sh \
+ mmjsonparse-invalid-containerName.sh \
+ wtpShutdownAll-assertionFailure.sh \
+ imptcp-octet-framing-too-long-vg.sh \
+ imptcp-oversize-message-display.sh \
+ imptcp-msg-truncation-on-number.sh \
+ imptcp-msg-truncation-on-number2.sh \
+ imptcp-maxFrameSize-parameter.sh \
+ mmjsonparse_cim.sh \
+ mmjsonparse_cim2.sh \
+ mmjsonparse_localvar.sh \
+ mmdb.sh \
+ mmdb-space.sh \
+ mmdb.rb \
+ test.mmdb \
+ with_space.mmdb \
+ mmdb-vg.sh \
+ mmdb-container.sh \
+ mmdb-container-empty.sh \
+ mmdb-multilevel-vg.sh \
+ incltest.sh \
+ incltest_dir.sh \
+ incltest_dir_empty_wildcard.sh \
+ incltest_dir_wildcard.sh \
+ testsuites/es.yml \
+ clickhouse-dflt-tpl.sh \
+ clickhouse-retry-error.sh \
+ clickhouse-start.sh \
+ clickhouse-stop.sh \
+ clickhouse-basic.sh \
+ clickhouse-load.sh \
+ clickhouse-bulk.sh \
+ clickhouse-bulk-load.sh \
+ clickhouse-limited-batch.sh \
+ clickhouse-select.sh \
+ clickhouse-wrong-quotation-marks.sh \
+ clickhouse-wrong-template-option.sh \
+ clickhouse-errorfile.sh \
+ clickhouse-wrong-insert-syntax.sh \
+ clickhouse-basic-vg.sh \
+ clickhouse-load-vg.sh \
+ clickhouse-bulk-vg.sh \
+ clickhouse-bulk-load-vg.sh \
+ es_response_get_msgnum.py \
+ elasticsearch-error-format-check.py \
+ es-duplicated-ruleset.sh \
+ es-duplicated-ruleset-vg.sh \
+ es-basic-es6.0.sh \
+ es-basic-es7.14.sh \
+ es-basic.sh \
+ es-basic-vgthread.sh \
+ es-basic-server.sh \
+ es-execOnlyWhenPreviousSuspended.sh \
+ es-basic-ha.sh \
+ es-basic-bulk.sh \
+ es-basic-errfile-empty.sh \
+ es-basic-errfile-popul.sh \
+ es-bulk-errfile-empty.sh \
+ es-bulk-errfile-popul.sh \
+ es-bulk-errfile-popul-def-format.sh \
+ es-bulk-errfile-popul-erronly.sh \
+ es-bulk-errfile-popul-erronly-interleaved.sh \
+ es-bulk-errfile-popul-def-interleaved.sh \
+ es-searchType-empty.sh \
+ diskqueue-multithread-es.sh \
+ es-basic-vg.sh \
+ es-basic-bulk-vg.sh \
+ es-basic-ha-vg.sh \
+ es-maxbytes-bulk.sh \
+ es-bulk-retry.sh \
+ elasticsearch-stop.sh \
+ linkedlistqueue.sh \
+ da-mainmsg-q.sh \
+ diskqueue-fsync.sh \
+ msgdup.sh \
+ msgdup_props.sh \
+ empty-ruleset.sh \
+ ruleset-direct-queue.sh \
+ imtcp-listen-port-file-2.sh \
+ allowed-sender-tcp-ok.sh \
+ allowed-sender-tcp-fail.sh \
+ allowed-sender-tcp-hostname-ok.sh \
+ allowed-sender-tcp-hostname-fail.sh \
+ imtcp-octet-framing-too-long-vg.sh \
+ imtcp-discard-truncated-msg.sh \
+ imtcp-basic.sh \
+ imtcp-basic-hup.sh \
+ imtcp-maxFrameSize.sh \
+ imtcp-msg-truncation-on-number.sh \
+ imtcp-msg-truncation-on-number2.sh \
+ imtcp-NUL.sh \
+ imtcp-NUL-rawmsg.sh \
+ imtcp-tls-gtls-x509fingerprint-invld.sh \
+ imtcp-tls-gtls-x509fingerprint.sh \
+ imtcp-tls-gtls-x509name-invld.sh \
+ imtcp-tls-gtls-x509name.sh \
+ imtcp-tls-gtls-x509name-legacy.sh \
+ imtcp-drvr-in-input-basic.sh \
+ imtcp-multi-drvr-basic.sh \
+ imtcp-multi-drvr-basic-parallel.sh \
+ imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh \
+ imtcp-tls-basic.sh \
+ imtcp-tls-input-basic.sh \
+ imtcp-tls-input-2certs.sh \
+ imtcp-tls-basic-verifydepth.sh \
+ imtcp-tls-basic-vg.sh \
+ imtcp-tls-no-lstn-startup.sh \
+ imtcp_incomplete_frame_at_end.sh \
+ imtcp-multiport.sh \
+ imtcp-bigmessage-octetcounting.sh \
+ imtcp-bigmessage-octetstuffing.sh \
+ udp-msgreduc-orgmsg-vg.sh \
+ udp-msgreduc-vg.sh \
+ manytcp-too-few-tls-vg.sh \
+ imtcp-tls-ossl-basic.sh \
+ imtcp-tls-ossl-input-basic.sh \
+ imtcp-tls-ossl-input-2certs.sh \
+ imtcp-tls-ossl-basic-tlscommands.sh \
+ imtcp-tls-ossl-basic-verifydepth.sh \
+ imtcp-tls-ossl-invalid-verifydepth.sh \
+ sndrcv_tls_ossl_anon_ipv4.sh \
+ sndrcv_tls_ossl_anon_ipv6.sh \
+ sndrcv_tls_ossl_anon_rebind.sh \
+ sndrcv_tls_ossl_anon_ciphers.sh \
+ sndrcv_tls_ossl_certvalid.sh \
+ sndrcv_tls_ossl_certvalid_action_level.sh \
+ sndrcv_tls_ossl_certvalid_expired.sh \
+ sndrcv_tls_ossl_certvalid_tlscommand.sh \
+ sndrcv_tls_ossl_certvalid_ciphers.sh \
+ sndrcv_tls_ossl_certvalid_revoked.sh \
+ imtcp-tls-ossl-x509valid.sh \
+ imtcp-tls-ossl-x509name.sh \
+ imtcp-tls-ossl-x509fingerprint.sh \
+ imtcp-tls-ossl-basic-vg.sh \
+ imtcp-tls-ossl-basic-brokenhandshake-vg.sh \
+ imtcp-tls-ossl-error-ca.sh \
+ imtcp-tls-ossl-error-cert.sh \
+ imtcp-tls-ossl-error-key.sh \
+ imtcp-tls-ossl-error-key2.sh \
+ manytcp.sh \
+ manyptcp.sh \
+ imptcp-basic-hup.sh \
+ imptcp-NUL.sh \
+ imptcp-NUL-rawmsg.sh \
+ imptcp_framing_regex.sh \
+ testsuites/imptcp_framing_regex.testdata \
+ imptcp_framing_regex-oversize.sh \
+ testsuites/imptcp_framing_regex-oversize.testdata \
+ imptcp_large.sh \
+ imptcp-connection-msg-disabled.sh \
+ imptcp-connection-msg-received.sh \
+ imptcp-discard-truncated-msg.sh \
+ imptcp_addtlframedelim.sh \
+ imptcp_conndrop-vg.sh \
+ imptcp_conndrop.sh \
+ imptcp_multi_line.sh \
+ testsuites/imptcp_multi_line.testdata \
+ imptcp_no_octet_counted.sh \
+ imtcp_addtlframedelim_on_input.sh \
+ testsuites/no_octet_counted.testdata \
+ imtcp_no_octet_counted.sh \
+ testsuites/spframingfix.testdata \
+ imtcp_spframingfix.sh \
+ imtcp-connection-msg-recieved.sh \
+ imptcp_spframingfix.sh \
+ msg-deadlock-headerless-noappname.sh \
+ imtcp_conndrop.sh \
+ imtcp_conndrop_tls.sh \
+ imtcp_conndrop_tls-vg.sh \
+ imtcp_addtlframedelim.sh \
+ tcp-msgreduc-vg.sh \
+ inputname-imtcp.sh \
+ omod-if-array.sh \
+ omod-if-array-udp.sh \
+ discard.sh \
+ failover-no-rptd.sh \
+ failover-no-rptd-vg.sh \
+ failover-no-basic.sh \
+ failover-no-basic-vg.sh \
+ failover-rptd.sh \
+ failover-rptd-vg.sh \
+ failover-basic.sh \
+ failover-basic-vg.sh \
+ failover-async.sh \
+ failover-double.sh \
+ suspend-via-file.sh \
+ suspend-omfwd-via-file.sh \
+ externalstate-failed-rcvr.sh \
+ discard-rptdmsg.sh \
+ discard-rptdmsg-vg.sh \
+ discard-allmark.sh \
+ discard-allmark-vg.sh \
+ diag.sh \
+ rcvr_fail_restore.sh \
+ queue-encryption-disk.sh \
+ queue-encryption-disk_keyfile.sh \
+ queue-encryption-disk_keyfile-vg.sh \
+ queue-encryption-disk_keyprog.sh \
+ queue-encryption-da.sh \
+ da-queue-persist.sh \
+ daqueue-dirty-shutdown.sh \
+ daqueue-invld-qi.sh \
+ daqueue-persist.sh \
+ daqueue-persist-drvr.sh \
+ queue-persist.sh \
+ queue-persist-drvr.sh \
+ threadingmq.sh \
+ threadingmqaq.sh \
+ sndrcv_drvr.sh \
+ sndrcv_drvr_noexit.sh \
+ sndrcv_failover.sh \
+ sndrcv.sh \
+ omrelp_errmsg_no_connect.sh \
+ imrelp-basic.sh \
+ imrelp-basic-hup.sh \
+ imrelp-basic-vg.sh \
+ imrelp-basic-oldstyle.sh \
+ imrelp-manyconn.sh \
+ imrelp-manyconn-vg.sh \
+ imrelp-maxDataSize-error.sh \
+ imrelp-long-msg.sh \
+ imrelp-oversizeMode-truncate.sh \
+ imrelp-oversizeMode-accept.sh \
+ imrelp-invld-tlslib.sh \
+ imrelp-bigmessage.sh \
+ imrelp-sessionbreak-vg.sh \
+ omrelp-invld-tlslib.sh \
+ glbl-oversizeMsg-log.sh \
+ glbl-oversizeMsg-truncate.sh \
+ glbl-oversizeMsg-split.sh \
+ sndrcv_relp.sh \
+ sndrcv_relp_rebind.sh \
+ sndrcv_relp_tls_prio.sh \
+ sndrcv_relp_tls_chainedcert.sh \
+ sndrcv_relp_tls.sh \
+ sndrcv_relp_tls_certvalid.sh \
+ sndrcv_relp-vg-rcvr.sh \
+ sndrcv_relp-vg-sender.sh \
+ relp_tls_certificate_not_found.sh \
+ omrelp_wrong_authmode.sh \
+ imrelp-tls.sh \
+ imrelp-tls-cfgcmd.sh \
+ imrelp-tls-chainedcert.sh \
+ imrelp-tls-mixed-chainedcert.sh \
+ imrelp-tls-mixed-chainedcert2.sh \
+ sndrcv_relp_tls-cfgcmd.sh \
+ sndrcv_relp_dflt_pt.sh \
+ sndrcv_udp.sh \
+ imudp_thread_hang.sh \
+ sndrcv_udp_nonstdpt.sh \
+ sndrcv_udp_nonstdpt_v6.sh \
+ omudpspoof_errmsg_no_params.sh \
+ sndrcv_omudpspoof.sh \
+ sndrcv_omudpspoof-bigmsg.sh \
+ sndrcv_omudpspoof_nonstdpt.sh \
+ sndrcv_gzip.sh \
+ imdtls-basic.sh \
+ imdtls-basic-tlscommands.sh \
+ imdtls-basic-timeout \
+ imdtls-error-cert.sh \
+ imdtls-sessionbreak.sh \
+ imdtls-basic-vg.sh \
+ imdtls-sessionbreak-vg.sh \
+ sndrcv_dtls_certvalid.sh \
+ sndrcv_dtls_anon_ciphers.sh \
+ sndrcv_dtls_certvalid_ciphers.sh \
+ sndrcv_dtls_certvalid_permitted.sh \
+ sndrcv_dtls_certvalid_missing.sh \
+ sndrcv_dtls_anon_ciphers.sh \
+ sndrcv_dtls_certvalid-vg.sh \
+ action-tx-single-processing.sh \
+ omfwd-errfile-maxsize.sh \
+ omfwd-errfile-maxsize-filled.sh \
+ action-tx-errfile-maxsize.sh \
+ action-tx-errfile.sh \
+ testsuites/action-tx-errfile.result \
+ pipeaction.sh \
+ improg-simul.sh \
+ improg-multiline-test.py \
+ improg_errmsg_no_params.sh \
+ improg_errmsg_no_params-vg.sh \
+ improg_prog_simple.sh \
+ improg_prog_confirm.sh \
+ improg_prog_confirm_killonclose.sh \
+ improg_prog_killonclose.sh \
+ improg_prog_simple-vg.sh \
+ improg_simple_multi.sh \
+ imhttp-post-payload.sh \
+ imhttp-post-payload-vg.sh \
+ imhttp-post-payload-basic-auth.sh \
+ imhttp-post-payload-basic-auth-vg.sh \
+ imhttp-post-payload-query-params.sh \
+ imhttp-post-payload-query-params-vg.sh \
+ imhttp-post-payload-large.sh \
+ imhttp-post-payload-large-vg.sh \
+ testsuites/imhttp-large-data.txt \
+ imhttp-post-payload-multi.sh \
+ imhttp-post-payload-multi-vg.sh \
+ imhttp-getrequest-file.sh \
+ imhttp-getrequest-file-vg.sh \
+ imhttp-post-payload-multi-lf.sh \
+ imhttp-post-payload-multi-lf-vg.sh \
+ imhttp-post-payload-compress.sh \
+ imhttp-post-payload-compress-vg.sh \
+ testsuites/docroot/file.txt \
+ testsuites/htpasswd \
+ omhttp-auth.sh \
+ omhttp-basic.sh \
+ omhttp-batch-fail-with-400.sh \
+ omhttp-batch-jsonarray-compress.sh \
+ omhttp-batch-jsonarray-retry.sh \
+ omhttp-batch-jsonarray.sh \
+ omhttp-batch-kafkarest-retry.sh \
+ omhttp-batch-kafkarest.sh \
+ omhttp-batch-lokirest-retry.sh \
+ omhttp-batch-lokirest.sh \
+ omhttp-batch-lokirest-vg.sh \
+ omhttp-batch-newline.sh \
+ omhttp-retry.sh \
+ omhttp-httpheaderkey.sh \
+ omhttp-multiplehttpheaders.sh \
+ omhttp-dynrestpath.sh \
+ omhttp-batch-dynrestpath.sh \
+ omhttp-auth-vg.sh \
+ omhttp-basic-vg.sh \
+ omhttp-batch-jsonarray-compress-vg.sh \
+ omhttp-batch-jsonarray-retry-vg.sh \
+ omhttp-batch-jsonarray-vg.sh \
+ omhttp-batch-kafkarest-retry-vg.sh \
+ omhttp-batch-lokirest-retry-vg.sh \
+ omhttp-retry-vg.sh \
+ omhttp_server.py \
+ omprog-defaults.sh \
+ omprog-defaults-vg.sh \
+ omprog-output-capture.sh \
+ omprog-output-capture-mt.sh \
+ omprog-output-capture-vg.sh \
+ omprog-feedback.sh \
+ omprog-feedback-mt.sh \
+ omprog-feedback-vg.sh \
+ omprog-feedback-timeout.sh \
+ omprog-close-unresponsive.sh \
+ omprog-close-unresponsive-vg.sh \
+ omprog-close-unresponsive-noterm.sh \
+ omprog-restart-terminated.sh \
+ omprog-restart-terminated-vg.sh \
+ omprog-restart-terminated-outfile.sh \
+ omprog-single-instance.sh \
+ omprog-single-instance-vg.sh \
+ omprog-single-instance-outfile.sh \
+ omprog-if-error.sh \
+ omprog-transactions.sh \
+ omprog-transactions-vg.sh \
+ omprog-transactions-failed-messages.sh \
+ omprog-transactions-failed-commits.sh \
+ testsuites/omprog-defaults-bin.sh \
+ testsuites/omprog-output-capture-bin.sh \
+ testsuites/omprog-output-capture-mt-bin.py \
+ testsuites/omprog-feedback-bin.sh \
+ testsuites/omprog-feedback-mt-bin.sh \
+ testsuites/omprog-feedback-timeout-bin.sh \
+ testsuites/omprog-close-unresponsive-bin.sh \
+ testsuites/omprog-restart-terminated-bin.sh \
+ testsuites/omprog-single-instance-bin.sh \
+ testsuites/omprog-transactions-bin.sh \
+ pipe_noreader.sh \
+ uxsock_simple.sh \
+ asynwr_simple.sh \
+ asynwr_simple_2.sh \
+ asynwr_timeout.sh \
+ asynwr_timeout_2.sh \
+ asynwr_small.sh \
+ asynwr_tinybuf.sh \
+ wr_large_async.sh \
+ wr_large_sync.sh \
+ asynwr_deadlock.sh \
+ asynwr_deadlock_2.sh \
+ asynwr_deadlock2.sh \
+ asynwr_deadlock4.sh \
+ asynwr_dynfile_flushtxend-off.sh \
+ abort-uncleancfg-goodcfg.sh \
+ abort-uncleancfg-goodcfg-check.sh \
+ abort-uncleancfg-badcfg-check.sh \
+ abort-uncleancfg-badcfg-check_1.sh \
+ variable_leading_underscore.sh \
+ gzipwr_hup_multi_file.sh \
+ gzipwr_hup_single_file.sh \
+ gzipwr_rscript.sh \
+ gzipwr_flushInterval.sh \
+ gzipwr_flushOnTXEnd.sh \
+ gzipwr_large.sh \
+ gzipwr_large_dynfile.sh \
+ gzipwr_hup.sh \
+ complex1.sh \
+ random.sh \
+ testsuites/imfile-old-state-file_imfile-state_.-rsyslog.input \
+ imfile-readmode0-vg.sh \
+ imfile-readmode2.sh \
+ imfile-readmode2-polling.sh \
+ imfile-readmode2-vg.sh \
+ imfile-readmode2-with-persists-data-during-stop.sh \
+ imfile-readmode2-with-persists.sh \
+ imfile-endregex-save-lf.sh \
+ imfile-endregex-save-lf-persist.sh \
+ imfile-endregex.sh \
+ imfile-endregex-vg.sh \
+ imfile-basic.sh \
+ imfile-basic-legacy.sh \
+ imfile-basic-2GB-file.sh \
+ imfile-truncate-2GB-file.sh \
+ imfile-discard-truncated-line.sh \
+ imfile-truncate-line.sh \
+ imfile-file-not-found-error.sh \
+ imfile-fileNotFoundError-parameter.sh \
+ imfile-error-not-repeated.sh \
+ imfile-basic-vg.sh \
+ imfile-basic-vgthread.sh \
+ imfile-endregex-timeout-none-polling.sh \
+ imfile-endregex-timeout-polling.sh \
+ imfile-endregex-timeout.sh \
+ imfile-endregex-timeout-none.sh \
+ imfile-endregex-timeout-with-shutdown.sh \
+ imfile-endregex-timeout-with-shutdown-polling.sh \
+ imfile-escapelf.replacement.sh \
+ imfile-escapelf.replacement-empty.sh \
+ imfile-endmsg.regex.sh \
+ imfile-endmsg.regex-vg.sh \
+ imfile-endmsg.regex-with-example.sh \
+ imfile-endmsg.regex-with-example-vg.sh \
+ imfile-endmsg.regex.crio.rulebase \
+ imfile-endmsg.regex.json.rulebase \
+ imfile-statefile-no-file_id.sh \
+ imfile-statefile-no-file_id-TO-file_id.sh \
+ imfile-statefile-directory.sh \
+ imfile-statefile-delete.sh \
+ imfile-statefile-no-delete.sh \
+ imfile-persist-state-1.sh \
+ imfile-freshStartTail1.sh \
+ imfile-freshStartTail2.sh \
+ imfile-freshStartTail3.sh \
+ imfile-truncate.sh \
+ imfile-truncate-multiple.sh \
+ imfile-wildcards.sh \
+ imfile-wildcards-dirs.sh \
+ imfile-wildcards-dirs2.sh \
+ imfile-wildcards-dirs-multi.sh \
+ imfile-wildcards-dirs-multi2.sh \
+ imfile-wildcards-dirs-multi3.sh \
+ imfile-wildcards-dirs-multi4.sh \
+ imfile-wildcards-dirs-multi5.sh \
+ imfile-wildcards-dirs-multi5-polling.sh \
+ imfile-old-state-file.sh \
+ imfile-rename-while-stopped.sh \
+ imfile-rename.sh \
+ imfile-symlink.sh \
+ imfile-symlink-multi.sh \
+ imfile-symlink-ext-tmp-dir-tree.sh \
+ imfile-logrotate.sh \
+ imfile-logrotate-async.sh \
+ imfile-logrotate-copytruncate.sh \
+ imfile-logrotate-nocopytruncate.sh \
+ imfile-logrotate-multiple.sh \
+ imfile-growing-file-id.sh \
+ imfile-ignore-old-file-1.sh \
+ imfile-ignore-old-file-2.sh \
+ imfile-ignore-old-file-3.sh \
+ imfile-ignore-old-file-4.sh \
+ imfile-ignore-old-file-5.sh \
+ imfile-ignore-old-file-6.sh \
+ imfile-ignore-old-file-7.sh \
+ glbl-oversizeMsg-truncate-imfile.sh \
+ dynfile_invld_async.sh \
+ dynfile_invld_sync.sh \
+ dynfile_invalid2.sh \
+ rulesetmultiqueue.sh \
+ rulesetmultiqueue-v6.sh \
+ omruleset.sh \
+ omruleset-queue.sh \
+ badqi.sh \
+ bad_qi/dbq.qi \
+ execonlyonce.sh \
+ execonlywhenprevsuspended.sh \
+ execonlywhenprevsuspended2.sh \
+ execonlywhenprevsuspended3.sh \
+ execonlywhenprevsuspended4.sh \
+ execonlywhenprevsuspended_multiwrkr.sh \
+ execonlywhenprevsuspended-queue.sh \
+ execonlywhenprevsuspended-nonsusp.sh \
+ execonlywhenprevsuspended-nonsusp-queue.sh \
+ tabescape_dflt.sh \
+ tabescape_dflt-udp.sh \
+ tabescape_off.sh \
+ tabescape_off-udp.sh \
+ tabescape_on.sh \
+ dircreate_dflt.sh \
+ dircreate_off.sh \
+ imuxsock_legacy.sh \
+ imuxsock_logger_parserchain.sh \
+ imuxsock_logger.sh \
+ imuxsock_logger_ratelimit.sh \
+ imuxsock_logger_ruleset.sh \
+ imuxsock_logger_ruleset_ratelimit.sh \
+ imuxsock_logger_err.sh \
+ imuxsock_logger_root.sh \
+ imuxsock_logger_syssock.sh \
+ imuxsock_traillf.sh \
+ imuxsock_traillf_root.sh \
+ imuxsock_traillf_syssock.sh \
+ imuxsock_ccmiddle.sh \
+ imuxsock_ccmiddle_root.sh \
+ imklog_permitnonkernelfacility_root.sh \
+ imuxsock_ccmiddle_syssock.sh \
+ imuxsock_hostname.sh \
+ testsuites/mysql-truncate.sql \
+ testsuites/mysql-select-msg.sql \
+ libdbi-basic.sh \
+ libdbi-asyn.sh \
+ mysqld-start.sh \
+ mysqld-stop.sh \
+ mysql-basic.sh \
+ mysql-basic-cnf6.sh \
+ mysql-basic-vg.sh \
+ mysql-asyn.sh \
+ mysql-asyn-vg.sh \
+ mysql-actq-mt.sh \
+ mysql-actq-mt-withpause.sh \
+ mysql-actq-mt-withpause-vg.sh \
+ kafka-selftest.sh \
+ omkafka.sh \
+ omkafkadynakey.sh \
+ omkafka-vg.sh \
+ imkafka-hang-on-no-kafka.sh \
+ imkafka-hang-other-action-on-no-kafka.sh \
+ imkafka-backgrounded.sh \
+ imkafka-config-err-ruleset.sh \
+ imkafka-config-err-param.sh \
+ imkafka.sh \
+ imkafka-vg.sh \
+ imkafka_multi_single.sh \
+ imkafka_multi_group.sh \
+ sndrcv_kafka.sh \
+ sndrcv_kafka_multi_topics.sh \
+ testsuites/kafka-server.properties \
+ testsuites/kafka-server.dep_wrk1.properties \
+ testsuites/kafka-server.dep_wrk2.properties \
+ testsuites/kafka-server.dep_wrk3.properties \
+ testsuites/zoo.cfg \
+ testsuites/zoo.dep_wrk1.cfg \
+ testsuites/zoo.dep_wrk2.cfg \
+ testsuites/zoo.dep_wrk3.cfg \
+ omazureeventhubs-basic.sh \
+ omazureeventhubs-list.sh \
+ omazureeventhubs-stress.sh \
+ omazureeventhubs-interrupt.sh \
+ omazureeventhubs-basic-vg.sh \
+ omazureeventhubs-interrupt-vg.sh \
+ mmpstrucdata.sh \
+ mmpstrucdata-escaping.sh \
+ mmpstrucdata-case.sh \
+ mmpstrucdata-vg.sh \
+ mmpstrucdata-invalid-vg.sh \
+ libdbi-basic-vg.sh \
+ dynstats_ctr_reset.sh \
+ dynstats_reset_without_pstats_reset.sh \
+ dynstats_nometric.sh \
+ dynstats_overflow.sh \
+ dynstats_overflow-vg.sh \
+ dynstats_reset.sh \
+ dynstats_reset-vg.sh \
+ impstats-hup.sh \
+ dynstats.sh \
+ dynstats-vg.sh \
+ dynstats_prevent_premature_eviction.sh \
+ dynstats_prevent_premature_eviction-vg.sh \
+ testsuites/dynstats_empty_input \
+ testsuites/dynstats_input \
+ testsuites/dynstats_input_1 \
+ testsuites/dynstats_input_2 \
+ testsuites/dynstats_input_3 \
+ testsuites/dynstats_input_more_0 \
+ testsuites/dynstats_input_more_1 \
+ testsuites/dynstats_input_more_2 \
+ no-dynstats-json.sh \
+ no-dynstats.sh \
+ omfwd_impstats-udp.sh \
+ omfwd_impstats-tcp.sh \
+ perctile-simple.sh \
+ perctile-simple-vg.sh \
+ stats-json.sh \
+ stats-json-vg.sh \
+ stats-cee.sh \
+ stats-cee-vg.sh \
+ stats-json-es.sh \
+ dynstats-json.sh \
+ dynstats-json-vg.sh \
+ mmnormalize_variable.sh \
+ mmnormalize_tokenized.sh \
+ testsuites/mmnormalize_variable.rulebase \
+ testsuites/date_time_msg \
+ testsuites/mmnormalize_tokenized.rulebase \
+ testsuites/tokenized_input \
+ rscript_random.sh \
+ rscript_hash32.sh \
+ rscript_hash32-vg.sh \
+ rscript_hash64.sh \
+ rscript_hash64-vg.sh \
+ rscript_replace.sh \
+ rscript_replace_complex.sh \
+ testsuites/complex_replace_input \
+ rscript_unaffected_reset.sh \
+ rscript_wrap2.sh \
+ rscript_wrap3.sh \
+ testsuites/wrap3_input\
+ json_array_subscripting.sh \
+ testsuites/json_array_input \
+ testsuites/json_object_input \
+ testsuites/json_nonarray_input \
+ json_array_looping.sh \
+ json_object_looping.sh \
+ json_object_looping-vg.sh \
+ json_array_looping-vg.sh \
+ json_object_suicide_in_loop-vg.sh \
+ json_nonarray_looping.sh \
+ json_null.sh \
+ json_null-vg.sh \
+ json_null_array.sh \
+ json_null_array-vg.sh \
+ mmjsonparse_extra_data-vg.sh \
+ mmnormalize_regex.sh \
+ testsuites/mmnormalize_regex.rulebase \
+ testsuites/regex_input \
+ mmnormalize_regex_disabled.sh \
+ mmnormalize_regex_defaulted.sh \
+ stop_when_array_has_element.sh \
+ testsuites/stop_when_array_has_elem_input \
+ key_dereference_on_uninitialized_variable_space.sh \
+ rscript_re_extract_i.sh \
+ rscript_re_extract.sh \
+ rscript_re_match_i.sh \
+ rscript_re_match.sh \
+ rscript_re_match-dbl_quotes.sh \
+ lookup_table.sh \
+ lookup_table-hup-backgrounded.sh \
+ lookup_table_no_hup_reload.sh \
+ lookup_table_no_hup_reload-vg.sh \
+ lookup_table_rscript_reload.sh \
+ lookup_table_rscript_reload_without_stub.sh \
+ lookup_table_rscript_reload-vg.sh \
+ lookup_table_rscript_reload_without_stub-vg.sh \
+ rscript_trim-vg.sh \
+ testsuites/xlate.lkp_tbl \
+ testsuites/xlate_more.lkp_tbl \
+ unused_lookup_table-vg.sh \
+ lookup_table-vg.sh \
+ array_lookup_table.sh \
+ array_lookup_table-vg.sh \
+ array_lookup_table_misuse-vg.sh \
+ multiple_lookup_tables.sh \
+ multiple_lookup_tables-vg.sh \
+ testsuites/xlate_array.lkp_tbl \
+ testsuites/xlate_array_more.lkp_tbl \
+ testsuites/xlate_array_misuse.lkp_tbl \
+ testsuites/xlate_array_more_misuse.lkp_tbl \
+ sparse_array_lookup_table.sh \
+ sparse_array_lookup_table-vg.sh \
+ testsuites/xlate_sparse_array.lkp_tbl \
+ testsuites/xlate_sparse_array_more.lkp_tbl \
+ lookup_table_bad_configs.sh \
+ lookup_table_bad_configs-vg.sh \
+ testsuites/xlate_array_empty_table.lkp_tbl \
+ testsuites/xlate_array_no_index.lkp_tbl \
+ testsuites/xlate_array_no_table.lkp_tbl \
+ testsuites/xlate_array_no_value.lkp_tbl \
+ testsuites/xlate_empty_file.lkp_tbl \
+ testsuites/xlate_incorrect_type.lkp_tbl \
+ testsuites/xlate_incorrect_version.lkp_tbl \
+ testsuites/xlate_sparseArray_empty_table.lkp_tbl \
+ testsuites/xlate_sparseArray_no_index.lkp_tbl \
+ testsuites/xlate_sparseArray_no_table.lkp_tbl \
+ testsuites/xlate_sparseArray_no_value.lkp_tbl \
+ testsuites/xlate_string_empty_table.lkp_tbl \
+ testsuites/xlate_string_no_index.lkp_tbl \
+ testsuites/xlate_string_no_table.lkp_tbl \
+ testsuites/xlate_string_no_value.lkp_tbl \
+ testsuites/xlate_invalid_json.lkp_tbl \
+ testsuites/xlate_array_more_with_duplicates_and_nomatch.lkp_tbl \
+ testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl \
+ testsuites/xlate_sparse_array_more_with_duplicates_and_nomatch.lkp_tbl \
+ json_var_cmpr.sh \
+ imptcp_maxsessions.sh \
+ imptcp_nonProcessingPoller.sh \
+ imptcp_veryLargeOctateCountedMessages.sh \
+ known_issues.supp \
+ libmaxmindb.supp \
+ travis/trusty.supp \
+ linux_localtime_r.supp \
+ CI/centos6-9.supp \
+ CI/centos7.supp \
+ CI/gcov.supp \
+ CI/ubuntu20.04.supp \
+ json_var_case.sh \
+ cfg.sh \
+ empty-prop-comparison.sh \
+ sndrcv_tls_anon_rebind.sh \
+ sndrcv_tls_anon_hostname.sh \
+ sndrcv_tls_anon_ipv4.sh \
+ sndrcv_tls_anon_ipv6.sh \
+ sndrcv_tls_priorityString.sh \
+ sndrcv_tls_certvalid.sh \
+ sndrcv_tls_certvalid_action_level.sh \
+ sndrcv_tls_certvalid_expired.sh \
+ sndrcv_tls_certvalid_expired_defaultmode.sh \
+ sndrcv_tls_certvalid_revoked.sh \
+ sndrcv_tls_certless_clientonly.sh \
+ sndrcv_tls_gtls_servercert_gtls_clientanon.sh \
+ sndrcv_tls_gtls_servercert_gtls_clientanon_legacy.sh \
+ sndrcv_tls_gtls_serveranon_gtls_clientanon.sh \
+ sndrcv_tls_ossl_serveranon_ossl_clientanon.sh \
+ sndrcv_tls_ossl_servercert_ossl_clientanon.sh \
+ sndrcv_tls_ossl_servercert_gtls_clientanon.sh \
+ sndrcv_tls_ossl_serveranon_gtls_clientanon.sh \
+ sndrcv_tls_gtls_servercert_ossl_clientanon.sh \
+ sndrcv_tls_gtls_serveranon_ossl_clientanon.sh \
+ sndrcv_tls_client_missing_cert.sh \
+ sndrcv_ossl_cert_chain.sh \
+ omtcl.sh \
+ omtcl.tcl \
+ pmsnare-default.sh \
+ pmsnare-default-udp.sh \
+ pmsnare-ccoff.sh \
+ pmsnare-ccoff-udp.sh \
+ pmsnare-ccdefault.sh \
+ pmsnare-ccdefault-udp.sh \
+ pmsnare-cccstyle.sh \
+ pmsnare-cccstyle-udp.sh \
+ pmsnare-ccbackslash.sh \
+ pmsnare-ccbackslash-udp.sh \
+ pmsnare-modoverride.sh \
+ pmsnare-modoverride-udp.sh \
+ pmlastmsg.sh \
+ pmlastmsg-udp.sh \
+ pgsql-basic.sh \
+ testsuites/pgsql-basic.sql \
+ testsuites/pgsql-select-msg.sql \
+ testsuites/pgsql-select-syslogtag.sql \
+ pgsql-basic-cnf6.sh \
+ pgsql-basic-threads-cnf6.sh \
+ pgsql-template.sh \
+ pgsql-template-cnf6.sh \
+ pgsql-actq-mt-withpause.sh \
+ pgsql-template-threads-cnf6.sh \
+ pgsql-basic-vg.sh \
+ pgsql-template-vg.sh \
+ pgsql-basic-cnf6-vg.sh \
+ pgsql-template-cnf6-vg.sh \
+ pgsql-actq-mt-withpause-vg.sh \
+ ../devtools/prep-mysql-db.sh \
+ ../devtools/prepare_clickhouse.sh \
+ mmkubernetes-basic.sh \
+ mmkubernetes-basic-vg.sh \
+ mmkubernetes_test_server.py \
+ mmkubernetes-basic.out.json \
+ mmkubernetes-cache-expire.sh \
+ mmkubernetes-cache-expire-vg.sh \
+ mmkubernetes-cache-expire.out.expected \
+ mmkubernetes.supp \
+ es-writeoperation.sh \
+ imdocker-basic.sh \
+ imdocker-basic-vg.sh \
+ imdocker-long-logline.sh \
+ imdocker-long-logline-vg.sh \
+ imdocker-new-logs-from-start.sh \
+ imdocker-new-logs-from-start-vg.sh \
+ imdocker-multi-line.sh \
+ imdocker-multi-line-vg.sh \
+ testsuites/incltest.d/include.conf \
+ testsuites/abort-uncleancfg-goodcfg.conf \
+ testsuites/include-std-omfile-action.conf \
+ testsuites/invalid.conf \
+ testsuites/valid.conf \
+ testsuites/variable_leading_underscore.conf \
+ omamqp1-common.sh \
+ omamqp1-basic.sh \
+ omamqp1-basic-vg.sh
+
+ourtail_SOURCES = ourtail.c
+msleep_SOURCES = msleep.c
+omrelp_dflt_port_SOURCES = omrelp_dflt_port.c
+mangle_qi_SOURCES = mangle_qi.c
+chkseq_SOURCES = chkseq.c
+check_relpEngineVersion = check_relpEngineVersion.c
+have_relpSrvSetOversizeMode = have_relpSrvSetOversizeMode.c
+have_relpEngineSetTLSLibByName = have_relpEngineSetTLSLibByName.c
+have_relpSrvSetTlsConfigCmd = have_relpSrvSetTlsConfigCmd.c
+test_id_SOURCES = test_id.c
+
+uxsockrcvr_SOURCES = uxsockrcvr.c
+uxsockrcvr_LDADD = $(SOL_LIBS)
+
+tcpflood_SOURCES = tcpflood.c
+tcpflood_CFLAGS = $(PTHREADS_CFLAGS) $(RELP_CFLAGS)
+tcpflood_CPPFLAGS = $(PTHREADS_CFLAGS) $(RELP_CFLAGS)
+tcpflood_LDADD = $(SOL_LIBS) $(PTHREADS_LIBS) $(RELP_LIBS)
+if ENABLE_GNUTLS
+tcpflood_CFLAGS += $(GNUTLS_CFLAGS)
+tcpflood_CPPFLAGS += $(GNUTLS_CFLAGS)
+tcpflood_LDADD += $(GNUTLS_LIBS)
+endif
+if ENABLE_OPENSSL
+tcpflood_CFLAGS += $(OPENSSL_CFLAGS)
+tcpflood_CPPFLAGS += $(OPENSSL_CFLAGS)
+tcpflood_LDADD += $(OPENSSL_LIBS)
+endif
+
+minitcpsrv_SOURCES = minitcpsrvr.c
+minitcpsrv_LDADD = $(SOL_LIBS)
+
+syslog_caller_SOURCES = syslog_caller.c
+syslog_caller_CPPFLAGS = $(LIBLOGGING_STDLOG_CFLAGS)
+syslog_caller_LDADD = $(SOL_LIBS) $(LIBLOGGING_STDLOG_LIBS)
+
+journal_print_SOURCES = journal_print.c
+journal_print_CPPFLAGS = $(LIBSYSTEMD_JOURNAL_CFLAGS)
+journal_print_LDADD = $(LIBSYSTEMD_JOURNAL_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)
+
+# rtinit tests disabled for the moment - also questionable if they
+# really provide value (after all, everything fails if rtinit fails...)
+#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) $(SOL_LIBS)
+#rt_init_LDFLAGS = -export-dynamic
+
+# same for basic rscript tests
+#rscript_SOURCES = rscript.c getline.c $(test_files)
+#rscript_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS)
+#rscript_LDADD = $(RSRT_LIBS) $(ZLIB_LIBS) $(PTHREADS_LIBS) $(SOL_LIBS)
+#rscript_LDFLAGS = -export-dynamic
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 0000000..485b8c5
--- /dev/null
+++ b/tests/Makefile.in
@@ -0,0 +1,4452 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@ENABLE_TESTBENCH_TRUE@check_PROGRAMS = ourtail$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ tcpflood$(EXEEXT) chkseq$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ msleep$(EXEEXT) randomgen$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ diagtalker$(EXEEXT) uxsockrcvr$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ syslog_caller$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ inputfilegen$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ minitcpsrv$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ omrelp_dflt_port$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ mangle_qi$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ have_relpSrvSetOversizeMode$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ have_relpEngineSetTLSLibByName$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ have_relpSrvSetTlsConfigCmd$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ check_relpEngineVersion$(EXEEXT) \
+@ENABLE_TESTBENCH_TRUE@ test_id$(EXEEXT) $(am__EXEEXT_1) \
+@ENABLE_TESTBENCH_TRUE@ $(am__EXEEXT_2)
+@ENABLE_IMJOURNAL_TRUE@@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_1 = journal_print
+@ENABLE_TESTBENCH_TRUE@TESTS = $(am__append_2) $(am__append_3) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_4) $(am__append_5) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_6) $(am__append_7) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_8) $(am__append_9) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_10) $(am__append_11) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_12) $(am__append_13) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_14) $(am__append_15) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_16) $(am__append_17) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_18) $(am__append_19) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_20) $(am__append_21) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_22) $(am__append_23) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_24) $(am__append_25) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_26) $(am__append_27) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_28) $(am__append_29) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_30) $(am__append_31) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_32) $(am__append_33) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_34) $(am__append_35) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_36) $(am__append_37) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_38) $(am__append_39) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_40) $(am__append_41) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_42) $(am__append_43) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_44) $(am__append_45) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_46) $(am__append_47) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_48) $(am__append_49) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_50) $(am__append_51) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_52) $(am__append_53) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_54) $(am__append_55) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_57) $(am__append_58) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_59) $(am__append_60) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_61) $(am__append_62) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_63) $(am__append_64) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_65) $(am__append_66) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_67) $(am__append_68) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_69) $(am__append_70) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_71) $(am__append_72) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_73) $(am__append_74) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_75) $(am__append_76) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_77) $(am__append_78) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_79) $(am__append_80) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_81) $(am__append_82) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_83) $(am__append_84) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_85) $(am__append_86) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_87) $(am__append_88) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_89) $(am__append_90) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_91) $(am__append_92) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_93) $(am__append_94) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_95) $(am__append_96) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_97) $(am__append_98) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_99) $(am__append_100) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_101) $(am__append_102) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_103) $(am__append_104) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_105) $(am__append_106) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_107) $(am__append_108) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_109) $(am__append_110) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_111) $(am__append_112) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_113) $(am__append_114) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_115) $(am__append_116) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_117) $(am__append_118) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_119) $(am__append_120) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_121) $(am__append_122) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_123) $(am__append_124) \
+@ENABLE_TESTBENCH_TRUE@ $(am__append_125) $(am__append_126)
+# the following test need to be serialized:
+
+# special "test" for stopping ES once all ES tests are done
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_2 = es-duplicated-ruleset.sh \
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@ es-basic-es6.0.sh \
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@ es-basic-es7.14.sh \
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@ es-basic.sh \
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@ es-basic-bulk.sh \
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@ elasticsearch-stop.sh
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_3 = \
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ es-duplicated-ruleset-vg.sh \
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ es-basic-vg.sh
+
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_HELGRIND_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_4 = \
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_HELGRIND_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ es-basic-vgthread.sh
+
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_5 = \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ es-basic-server.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ es-execOnlyWhenPreviousSuspended.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ es-maxbytes-bulk.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ es-basic-errfile-empty.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ es-basic-errfile-popul.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ es-bulk-errfile-empty.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ es-bulk-errfile-popul.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ es-searchType-empty.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ diskqueue-multithread-es.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ es-writeoperation.sh
+
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_6 = \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ es-basic-ha.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ es-bulk-retry.sh
+
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMFILE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_7 = \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMFILE_TRUE@@ENABLE_TESTBENCH_TRUE@ es-bulk-errfile-popul-def-format.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMFILE_TRUE@@ENABLE_TESTBENCH_TRUE@ es-bulk-errfile-popul-erronly.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMFILE_TRUE@@ENABLE_TESTBENCH_TRUE@ es-bulk-errfile-popul-erronly-interleaved.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMFILE_TRUE@@ENABLE_TESTBENCH_TRUE@ es-bulk-errfile-popul-def-interleaved.sh
+
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_8 = \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ es-basic-bulk-vg.sh \
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ es-basic-ha-vg.sh
+
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_9 = \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ immark.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ immark-inputname.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ immark-ruleset.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ immark-ruleset-custom-msg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ operatingstate-basic.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ operatingstate-empty.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ operatingstate-unclean.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ smtradfile.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ loadbalance.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ empty-hostname.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ timestamp-3164.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ timestamp-3339.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ timestamp-isoweek.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ timestamp-mysql.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ timestamp-pgsql.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ timestamp-subseconds.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ msleep_usage_output.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mangle_qi_usage_output.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ minitcpsrv_usage_output.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ test_id_usage_output.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ prop-programname.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ prop-programname-with-slashes.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ hostname-with-slash-pmrfc5424.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ hostname-with-slash-pmrfc3164.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ hostname-with-slash-dflt-invld.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ func-substring-invld-startpos.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ func-substring-large-endpos.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ func-substring-large-neg-endpos.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ func-substring-relative-endpos.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ hostname-with-slash-dflt-slash-valid.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ empty-app-name.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ stop-localvar.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ stop-msgvar.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl-ruleset-queue-defaults.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl-internalmsg_severity-info-shown.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl-internalmsg_severity-debug-shown.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl-internalmsg_severity-debug-not_shown.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl-umask.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl-unloadmodules.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl-invld-param.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl_setenv_2_vars.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl_setenv_err.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl_setenv_err_too_long.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl_setenv.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mmexternal-SegFault.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ nested-call-shutdown.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ dnscache-TTL-0.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ invalid_nested_include.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfwd-tls-invalid-permitExpiredCerts.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfwd-keepalive.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omusrmsg-errmsg-no-params.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omusrmsg-noabort.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfile-module-params.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfile-read-only-errmsg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfile-null-filename.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfile-whitespace-filename.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfile-read-only.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfile-outchannel.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfile_both_files_set.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfile_hup.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ msgvar-concurrency.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ localvar-concurrency.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ exec_tpl-concurrency.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_privdropuser.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_privdropuserid.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_privdropgroup.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_privdropgroupid.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ privdropuser.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ privdropuserid.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ privdropgroup.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ privdropgroupid.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ privdropabortonidfail.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ privdropabortonidfaillegacy.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ json-nonstring.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ json-onempty-at-end.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ template-json.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ template-pure-json.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ template-pos-from-to.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ template-pos-from-to-lowercase.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ template-pos-from-to-oversize.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ template-pos-from-to-oversize-lowercase.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ template-pos-from-to-missing-jsonvar.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ template-const-jsonf.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ template-topos-neg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_authpriv.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_local0.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_local7.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_mail.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_news.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_ftp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_ntp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_uucp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_invld1.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_invld2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_invld3.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ fac_invld4_rfc5424.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rfc5424parser-sp_at_msg_start.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ compresssp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ compresssp-stringtpl.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rawmsg-after-pri.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rfc5424parser.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ pmrfc3164-msgFirstSpace.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ pmrfc3164-AtSignsInHostname.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ pmrfc3164-AtSignsInHostname_off.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ pmrfc3164-tagEndingByColon.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ pmrfc3164-defaultTag.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ pmrfc3164-json.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ tcp_forwarding_tpl.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ tcp_forwarding_dflt_tpl.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ tcp_forwarding_retries.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mainq_actq_DA.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ queue_warnmsg-oversize.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ queue-minbatch.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ queue-minbatch-queuefull.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ queue-direct-with-no-params.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ queue-direct-with-params-given.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ arrayqueue.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ global_vars.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ no-parser-errmsg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ da-mainmsg-q.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ validation-run.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ msgdup.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ msgdup_props.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ empty-ruleset.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ ruleset-direct-queue.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-listen-port-file-2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ allowed-sender-tcp-ok.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ allowed-sender-tcp-fail.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ allowed-sender-tcp-hostname-ok.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ allowed-sender-tcp-hostname-fail.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-discard-truncated-msg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-basic.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-basic-hup.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-maxFrameSize.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-msg-truncation-on-number.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-msg-truncation-on-number2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-NUL.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-NUL-rawmsg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp_incomplete_frame_at_end.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-multiport.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-bigmessage-octetcounting.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-bigmessage-octetstuffing.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ da-queue-persist.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ daqueue-persist.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ daqueue-invld-qi.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ daqueue-dirty-shutdown.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ diskq-rfc5424.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ diskqueue.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ diskqueue-fsync.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ diskqueue-full.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ diskqueue-fail.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ diskqueue-non-unique-prefix.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rulesetmultiqueue.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rulesetmultiqueue-v6.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ manytcp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rsf_getenv.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ msg-deadlock-headerless-noappname.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp_conndrop.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp_addtlframedelim.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp_no_octet_counted.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp_addtlframedelim_on_input.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp_spframingfix.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-connection-msg-recieved.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_failover.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_gzip.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_udp_nonstdpt.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_udp_nonstdpt_v6.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imudp_thread_hang.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_udp_nonstdpt_v6.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ asynwr_simple.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ asynwr_simple_2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ asynwr_timeout.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ asynwr_timeout_2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ asynwr_small.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ asynwr_tinybuf.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ wr_large_async.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ wr_large_sync.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ asynwr_deadlock.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ asynwr_deadlock_2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ asynwr_deadlock2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ asynwr_deadlock4.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ asynwr_dynfile_flushtxend-off.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ abort-uncleancfg-goodcfg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ abort-uncleancfg-goodcfg-check.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ abort-uncleancfg-badcfg-check.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ abort-uncleancfg-badcfg-check_1.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ variable_leading_underscore.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ gzipwr_hup_multi_file.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ gzipwr_hup_single_file.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ gzipwr_rscript.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ gzipwr_flushInterval.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ gzipwr_flushOnTXEnd.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ gzipwr_large.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ gzipwr_large_dynfile.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ gzipwr_hup.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ dynfile_invld_async.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ dynfile_invld_sync.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ dynfile_invalid2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ complex1.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ queue-persist.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ pipeaction.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ execonlyonce.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ execonlywhenprevsuspended.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ execonlywhenprevsuspended2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ execonlywhenprevsuspended3.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ execonlywhenprevsuspended4.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ execonlywhenprevsuspended_multiwrkr.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ execonlywhenprevsuspended-queue.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ execonlywhenprevsuspended-nonsusp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ execonlywhenprevsuspended-nonsusp-queue.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ pipe_noreader.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ dircreate_dflt.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ dircreate_off.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_legacy.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_logger.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_logger_ratelimit.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_logger_ruleset.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_logger_ruleset_ratelimit.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_logger_err.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_logger_parserchain.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_traillf.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_ccmiddle.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_logger_syssock.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_traillf_syssock.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_ccmiddle_syssock.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ discard-rptdmsg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ discard-allmark.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ discard.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ stop.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ failover-async.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ failover-double.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ failover-basic.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ failover-rptd.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ failover-no-rptd.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ failover-no-basic.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ suspend-via-file.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ suspend-omfwd-via-file.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ externalstate-failed-rcvr.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rcvr_fail_restore.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_contains.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_bare_var_root.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_bare_var_root-empty.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_ipv42num.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_field.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_stop.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_stop2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_prifilt.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_optimizer1.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_ruleset_call.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_ruleset_call_indirect-basic.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_ruleset_call_indirect-var.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_ruleset_call_indirect-invld.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_set_unset_invalid_var.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_set_modify.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_unaffected_reset.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_replace_complex.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_wrap2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_wrap3.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_re_extract_i.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_re_extract.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_re_match_i.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_re_match.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_re_match-dbl_quotes.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_eq.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_eq_var.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_ge.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_ge_var.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_gt.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_gt_var.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_le.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_le_var.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_lt.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_lt_var.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_ne.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_ne_var.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_number_comparison_LE.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_number_comparison_LT.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_compare_str-numstr.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_compare_str-num.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_compare_numstr-str.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_compare_num-str.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_compare_numstr-numstr.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_compare_numstr-num.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_compare_num-numstr.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_compare_num-num.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_compare_str-str.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_num2ipv4.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_int2Hex.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_trim.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_substring.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_format_time.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_parse_time.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_is_time.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_script_error.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_parse_json.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_previous_action_suspended.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_str2num_negative.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_exists-yes.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_exists-yes2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_exists-not1.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_exists-not2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_exists-not3.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_exists-not4.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript-config_enable-on.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_get_property.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ config_output-o-option.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rs-cnum.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rs-substring.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rs-int2hex.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ empty-prop-comparison.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ rs_optimizer_pri.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ cee_simple.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ cee_diskqueue.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ incltest.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ incltest_dir.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ incltest_dir_wildcard.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ incltest_dir_empty_wildcard.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ linkedlistqueue.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ lookup_table.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ lookup_table-hup-backgrounded.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ lookup_table_no_hup_reload.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ key_dereference_on_uninitialized_variable_space.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ array_lookup_table.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sparse_array_lookup_table.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ lookup_table_bad_configs.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ lookup_table_rscript_reload.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ lookup_table_rscript_reload_without_stub.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ config_multiple_include.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ include-obj-text-from-file.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ include-obj-text-from-file-noexist.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ multiple_lookup_tables.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse1.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse1-udp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse2.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse2-udp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse_8bit_escape.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse_8bit_escape-udp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse3.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse3-udp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse_invld_regex.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse_invld_regex-udp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse-3164-buggyday.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse-3164-buggyday-udp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse-nodate.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-parse-nodate-udp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-snare_ccoff_udp.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest-snare_ccoff_udp2.sh
+
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_LIBZSTD_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_10 = \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_LIBZSTD_TRUE@@ENABLE_TESTBENCH_TRUE@ zstd.sh
+
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_LIBZSTD_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_11 = \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_LIBZSTD_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ zstd-vg.sh
+
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_LIBGCRYPT_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_12 = \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_LIBGCRYPT_TRUE@@ENABLE_TESTBENCH_TRUE@ queue-encryption-disk.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_LIBGCRYPT_TRUE@@ENABLE_TESTBENCH_TRUE@ queue-encryption-disk_keyfile.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_LIBGCRYPT_TRUE@@ENABLE_TESTBENCH_TRUE@ queue-encryption-disk_keyprog.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_LIBGCRYPT_TRUE@@ENABLE_TESTBENCH_TRUE@ queue-encryption-da.sh
+
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_13 = \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omusrmsg-noabort-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omfile_hup-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ gzipwr_hup-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ tcpflood_wrong_option_output.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imtcp-octet-framing-too-long-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ smtradfile-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ dnscache-TTL-0-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ include-obj-outside-control-flow-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ include-obj-in-if-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ include-obj-text-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_parse_json-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_backticks-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_backticks_empty_envvar-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript-config_enable-off-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_get_property-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ prop-jsonmesg-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmexternal-InvldProg-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ internal-errmsg-memleak-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ glbl-oversizeMsg-log-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_set_memleak-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ no-parser-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ discard-rptdmsg-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ discard-allmark-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ failover-basic-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ failover-rptd-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ failover-no-basic-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ failover-no-rptd-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ timereported-utc-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ udp-msgreduc-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ udp-msgreduc-orgmsg-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ tcp-msgreduc-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_field-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_number_comparison_LE-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_compare_str-str-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_compare_str-num-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_compare_str-numstr-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_compare_num-str-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_compare_numstr-str-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_compare_numstr-num-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_compare_numstr-numstr-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_compare_num-num-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_compare_num-numstr-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ unused_lookup_table-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ lookup_table-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ lookup_table_no_hup_reload-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ array_lookup_table-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ array_lookup_table_misuse-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ sparse_array_lookup_table-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ lookup_table_bad_configs-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ lookup_table_rscript_reload-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ lookup_table_rscript_reload_without_stub-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ multiple_lookup_tables-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ fac_local0-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ badqi.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ threadingmq.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ threadingmqaq.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ func-substring-invld-startpos-vg.sh \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_trim-vg.sh
+
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_LIBGCRYPT_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_14 = \
+@ENABLE_DEFAULT_TESTS_TRUE@@ENABLE_LIBGCRYPT_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ queue-encryption-disk_keyfile-vg.sh
+
+@ENABLE_SNMP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_15 = \
+@ENABLE_SNMP_TRUE@@ENABLE_TESTBENCH_TRUE@ omsnmp_errmsg_no_params.sh
+
+@ENABLE_SNMP_TESTS_TRUE@@ENABLE_SNMP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_16 = \
+@ENABLE_SNMP_TESTS_TRUE@@ENABLE_SNMP_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_omsnmpv1_udp.sh \
+@ENABLE_SNMP_TESTS_TRUE@@ENABLE_SNMP_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_omsnmpv1_udp_dynsource.sh \
+@ENABLE_SNMP_TESTS_TRUE@@ENABLE_SNMP_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_omsnmpv1_udp_invalidoid.sh
+
+@ENABLE_MMUTF8FIX_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_17 = \
+@ENABLE_MMUTF8FIX_TRUE@@ENABLE_TESTBENCH_TRUE@ mmutf8fix_no_error.sh
+
+@ENABLE_MAIL_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_18 = \
+@ENABLE_MAIL_TRUE@@ENABLE_TESTBENCH_TRUE@ ommail_errmsg_no_params.sh
+
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_19 = \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_with_debug.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_random_32_ipv4.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_random_cons_32_ipv4.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_recognize_ipv4.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_zero_12_ipv4.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_zero_33_ipv4.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_zero_8_ipv4.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_simple_12_ipv4.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_simple_33_ipv4.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_simple_8_ipv4.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_simple_mallformed_ipv4.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_random_128_ipv6.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_zero_128_ipv6.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_zero_96_ipv6.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_random_cons_128_ipv6.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_zero_50_ipv6.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_recognize_ipv6.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_zero_64_ipv6.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_both_modes_compatible.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_recognize_ipembedded.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_ipv6_port.sh \
+@ENABLE_MMANON_TRUE@@ENABLE_TESTBENCH_TRUE@ mmanon_random_cons_128_ipembedded.sh
+
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_20 = \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-start.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-basic.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-dflt-tpl.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-retry-error.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-load.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-bulk.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-bulk-load.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-limited-batch.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-select.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-errorfile.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-wrong-quotation-marks.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-wrong-template-option.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ clickhouse-wrong-insert-syntax.sh
+
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_21 = \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ clickhouse-basic-vg.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ clickhouse-load-vg.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ clickhouse-bulk-vg.sh \
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ clickhouse-bulk-load-vg.sh
+
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_22 = clickhouse-stop.sh
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_23 = \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ now_family_utc.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ now-utc.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ now-utc-ymd.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ now-utc-casecmp.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ now-unixtimestamp.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ timegenerated-ymd.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ timegenerated-uxtimestamp.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ timegenerated-uxtimestamp-invld.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ timegenerated-dateordinal.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ timegenerated-dateordinal-invld.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ timegenerated-utc.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ timegenerated-utc-legacy.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ timereported-utc.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_TESTBENCH_TRUE@ timereported-utc-legacy.sh
+
+# now come faketime tests that utilize mmnormalize - aka "no endif here"
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_24 = \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmnormalize_processing_test1.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmnormalize_processing_test2.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmnormalize_processing_test3.sh \
+@ENABLE_LIBFAKETIME_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmnormalize_processing_test4.sh
+
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_25 = \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@ pgsql-basic.sh \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@ pgsql-basic-cnf6.sh \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@ pgsql-basic-threads-cnf6.sh \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@ pgsql-template.sh \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@ pgsql-template-cnf6.sh \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@ pgsql-actq-mt-withpause.sh \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@ pgsql-template-threads-cnf6.sh
+
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_26 = \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ pgsql-basic-vg.sh \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ pgsql-template-vg.sh \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ pgsql-basic-cnf6-vg.sh \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ pgsql-template-cnf6-vg.sh \
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ pgsql-actq-mt-withpause-vg.sh
+
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_27 = \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mysqld-start.sh \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mysql-basic.sh \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mysql-basic-cnf6.sh \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mysql-asyn.sh \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mysql-actq-mt.sh \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mysql-actq-mt-withpause.sh \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ action-tx-single-processing.sh \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ action-tx-errfile-maxsize.sh \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ action-tx-errfile.sh
+
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_28 = \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mysql-basic-vg.sh \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mysql-asyn-vg.sh \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mysql-actq-mt-withpause-vg.sh
+
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_OMLIBDBI_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_29 = \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_OMLIBDBI_TRUE@@ENABLE_TESTBENCH_TRUE@ libdbi-basic.sh \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_OMLIBDBI_TRUE@@ENABLE_TESTBENCH_TRUE@ libdbi-asyn.sh
+
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_OMLIBDBI_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_30 = \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_OMLIBDBI_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ libdbi-basic-vg.sh
+
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_31 = mysqld-stop.sh
+@ENABLE_FMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_32 = \
+@ENABLE_FMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_http_request.sh
+
+@ENABLE_FMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_33 = \
+@ENABLE_FMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_http_request-vg.sh
+
+@ENABLE_ROOT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_34 = \
+@ENABLE_ROOT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_udp.sh \
+@ENABLE_ROOT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_logger_root.sh \
+@ENABLE_ROOT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_traillf_root.sh \
+@ENABLE_ROOT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imuxsock_ccmiddle_root.sh \
+@ENABLE_ROOT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imklog_permitnonkernelfacility_root.sh
+
+@ENABLE_IP_TRUE@@ENABLE_ROOT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_35 = tcp_forwarding_ns_tpl.sh
+@ENABLE_ROOT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_36 = \
+@ENABLE_ROOT_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmexternal-SegFault-empty-jroot-vg.sh
+
+@ENABLE_IMJOURNAL_TRUE@@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_37 = \
+@ENABLE_IMJOURNAL_TRUE@@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imjournal-basic.sh \
+@ENABLE_IMJOURNAL_TRUE@@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imjournal-statefile.sh
+
+@ENABLE_IMJOURNAL_TRUE@@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_38 = \
+@ENABLE_IMJOURNAL_TRUE@@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imjournal-basic-vg.sh \
+@ENABLE_IMJOURNAL_TRUE@@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imjournal-statefile-vg.sh
+
+@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_OMJOURNAL_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_39 = \
+@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_OMJOURNAL_TRUE@@ENABLE_TESTBENCH_TRUE@ omjournal-abort-template.sh \
+@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_OMJOURNAL_TRUE@@ENABLE_TESTBENCH_TRUE@ omjournal-abort-no-template.sh \
+@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_OMJOURNAL_TRUE@@ENABLE_TESTBENCH_TRUE@ omjournal-basic-template.sh \
+@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_OMJOURNAL_TRUE@@ENABLE_TESTBENCH_TRUE@ omjournal-basic-no-template.sh
+
+@ENABLE_IMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_40 = \
+@ENABLE_IMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ improg_errmsg_no_params.sh \
+@ENABLE_IMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ improg_prog_simple.sh \
+@ENABLE_IMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ improg_prog_confirm.sh \
+@ENABLE_IMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ improg_prog_confirm_killonclose.sh \
+@ENABLE_IMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ improg_prog_killonclose.sh \
+@ENABLE_IMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ improg_simple_multi.sh
+
+@ENABLE_IMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_41 = \
+@ENABLE_IMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ improg_errmsg_no_params-vg.sh \
+@ENABLE_IMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ improg_prog_simple-vg.sh
+
+@ENABLE_MMDARWIN_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_42 = \
+@ENABLE_MMDARWIN_TRUE@@ENABLE_TESTBENCH_TRUE@ mmdarwin_errmsg_no_params.sh \
+@ENABLE_MMDARWIN_TRUE@@ENABLE_TESTBENCH_TRUE@ mmdarwin_errmsg_no_sock.sh
+
+@ENABLE_MMDARWIN_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_43 = \
+@ENABLE_MMDARWIN_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmdarwin_errmsg_no_sock-vg.sh
+
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_44 = \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-defaults.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-output-capture.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-output-capture-mt.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-feedback.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-feedback-mt.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-feedback-timeout.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-close-unresponsive.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-close-unresponsive-noterm.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-restart-terminated.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-restart-terminated-outfile.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-single-instance.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-single-instance-outfile.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-transactions.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-if-error.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-transactions-failed-messages.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@ omprog-transactions-failed-commits.sh
+
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_45 = \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omprog-defaults-vg.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omprog-output-capture-vg.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omprog-feedback-vg.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omprog-close-unresponsive-vg.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omprog-restart-terminated-vg.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omprog-single-instance-vg.sh \
+@ENABLE_OMPROG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omprog-transactions-vg.sh
+
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_46 = \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-auth.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-basic.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-batch-fail-with-400.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-batch-jsonarray-compress.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-batch-jsonarray-retry.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-batch-jsonarray.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-batch-kafkarest-retry.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-batch-kafkarest.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-batch-lokirest-retry.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-batch-lokirest.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-batch-newline.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-retry.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-httpheaderkey.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-multiplehttpheaders.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-dynrestpath.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ omhttp-batch-dynrestpath.sh
+
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_47 = \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhttp-auth-vg.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhttp-basic-vg.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhttp-batch-jsonarray-compress-vg.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhttp-batch-jsonarray-retry-vg.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhttp-batch-jsonarray-vg.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhttp-batch-kafkarest-retry-vg.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhttp-batch-lokirest-retry-vg.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhttp-retry-vg.sh \
+@ENABLE_OMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhttp-batch-lokirest-vg.sh
+
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_48 = \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ kafka-selftest.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ omkafka.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ omkafkadynakey.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ imkafka.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ imkafka-backgrounded.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ imkafka-config-err-ruleset.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ imkafka-config-err-param.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ imkafka-hang-on-no-kafka.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ imkafka-hang-other-action-on-no-kafka.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ imkafka_multi_single.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ imkafka_multi_group.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_kafka.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_kafka_multi_topics.sh
+
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_49 = \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omkafka-vg.sh \
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imkafka-vg.sh
+
+@ENABLE_OMAZUREEVENTHUBS_TESTS_TRUE@@ENABLE_OMAZUREEVENTHUBS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_50 = \
+@ENABLE_OMAZUREEVENTHUBS_TESTS_TRUE@@ENABLE_OMAZUREEVENTHUBS_TRUE@@ENABLE_TESTBENCH_TRUE@ omazureeventhubs-basic.sh \
+@ENABLE_OMAZUREEVENTHUBS_TESTS_TRUE@@ENABLE_OMAZUREEVENTHUBS_TRUE@@ENABLE_TESTBENCH_TRUE@ omazureeventhubs-list.sh \
+@ENABLE_OMAZUREEVENTHUBS_TESTS_TRUE@@ENABLE_OMAZUREEVENTHUBS_TRUE@@ENABLE_TESTBENCH_TRUE@ omazureeventhubs-stress.sh \
+@ENABLE_OMAZUREEVENTHUBS_TESTS_TRUE@@ENABLE_OMAZUREEVENTHUBS_TRUE@@ENABLE_TESTBENCH_TRUE@ omazureeventhubs-interrupt.sh
+
+@ENABLE_OMAZUREEVENTHUBS_TESTS_TRUE@@ENABLE_OMAZUREEVENTHUBS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_51 = \
+@ENABLE_OMAZUREEVENTHUBS_TESTS_TRUE@@ENABLE_OMAZUREEVENTHUBS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omazureeventhubs-basic-vg.sh \
+@ENABLE_OMAZUREEVENTHUBS_TESTS_TRUE@@ENABLE_OMAZUREEVENTHUBS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omazureeventhubs-interrupt-vg.sh
+
+@ENABLE_IMDOCKER_TESTS_TRUE@@ENABLE_IMDOCKER_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_52 = \
+@ENABLE_IMDOCKER_TESTS_TRUE@@ENABLE_IMDOCKER_TRUE@@ENABLE_TESTBENCH_TRUE@ imdocker-basic.sh \
+@ENABLE_IMDOCKER_TESTS_TRUE@@ENABLE_IMDOCKER_TRUE@@ENABLE_TESTBENCH_TRUE@ imdocker-long-logline.sh \
+@ENABLE_IMDOCKER_TESTS_TRUE@@ENABLE_IMDOCKER_TRUE@@ENABLE_TESTBENCH_TRUE@ imdocker-new-logs-from-start.sh \
+@ENABLE_IMDOCKER_TESTS_TRUE@@ENABLE_IMDOCKER_TRUE@@ENABLE_TESTBENCH_TRUE@ imdocker-multi-line.sh
+
+@ENABLE_IMDOCKER_TESTS_TRUE@@ENABLE_IMDOCKER_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_53 = \
+@ENABLE_IMDOCKER_TESTS_TRUE@@ENABLE_IMDOCKER_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imdocker-basic-vg.sh \
+@ENABLE_IMDOCKER_TESTS_TRUE@@ENABLE_IMDOCKER_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imdocker-long-logline-vg.sh \
+@ENABLE_IMDOCKER_TESTS_TRUE@@ENABLE_IMDOCKER_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imdocker-new-logs-from-start-vg.sh \
+@ENABLE_IMDOCKER_TESTS_TRUE@@ENABLE_IMDOCKER_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imdocker-multi-line-vg.sh
+
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_54 = \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ imhttp-post-payload.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ imhttp-post-payload-basic-auth.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ imhttp-post-payload-query-params.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ imhttp-post-payload-large.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ imhttp-post-payload-multi.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ imhttp-post-payload-multi-lf.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ imhttp-post-payload-compress.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@ imhttp-getrequest-file.sh
+
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_55 = \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhttp-post-payload-vg.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhttp-post-payload-basic-auth-vg.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhttp-post-payload-query-params-vg.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhttp-post-payload-large-vg.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhttp-post-payload-multi-vg.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhttp-post-payload-multi-lf-vg.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhttp-post-payload-compress-vg.sh \
+@ENABLE_IMHTTP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhttp-getrequest-file-vg.sh
+
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_56 = miniamqpsrvr
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_57 = \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_no_params.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_params_missing0.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_params_missing1.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_params_missing2.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_params_invalid0.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_params_invalid1.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_params_invalid2.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_params_invalid3.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_data_1server.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_data_2servers.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_error_server0.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_error_server1.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_error_server2.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_error_server3.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_json.sh \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ omrabbitmq_raw.sh
+
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_58 = \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omrabbitmq_data_1server-vg.sh
+
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_59 = \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imhiredis-queue.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imhiredis-queue-lpop.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imhiredis-redis-restart.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imhiredis-redis-start-after.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imhiredis-subscribe.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imhiredis-stream.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imhiredis-stream-from-beginning.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imhiredis-stream-consumerGroup-ack.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imhiredis-stream-consumerGroup-noack.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imhiredis-stream-consumerGroup-reclaim.sh
+
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_60 = \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhiredis-queue-vg.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhiredis-queue-lpop-vg.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhiredis-redis-restart-vg.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhiredis-redis-start-after-vg.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhiredis-subscribe-vg.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhiredis-stream-vg.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhiredis-stream-from-beginning-vg.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhiredis-stream-consumerGroup-ack-vg.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhiredis-stream-consumerGroup-noack-vg.sh \
+@ENABLE_IMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imhiredis-stream-consumerGroup-reclaim-vg.sh
+
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_61 = \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mmdb-reload.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-dynakey.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-publish.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-queue-rpush.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-queue.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-set.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-setex.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-template.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-withpass.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-wrongpass.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-stream-ack.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-stream-capped.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-stream-del.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-stream-dynack.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-stream-outfield.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ omhiredis-stream.sh
+
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_62 = \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmdb-reload-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-dynakey-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-publish-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-queue-rpush-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-queue-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-set-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-setex-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-template-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-withpass-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-wrongpass-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-stream-ack-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-stream-capped-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-stream-del-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-stream-dynack-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-stream-outfield-vg.sh \
+@ENABLE_OMHIREDIS_TRUE@@ENABLE_REDIS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omhiredis-stream-vg.sh
+
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_63 = \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ impstats-hup.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ perctile-simple.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ dynstats.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ dynstats_overflow.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ dynstats_reset.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ dynstats_ctr_reset.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ dynstats_nometric.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ no-dynstats-json.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ no-dynstats.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ stats-json.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ dynstats-json.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ stats-cee.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ stats-json-es.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ dynstats_reset_without_pstats_reset.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ dynstats_prevent_premature_eviction.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfwd_fast_imuxsock.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfwd_impstats-udp.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@ omfwd_impstats-tcp.sh
+
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_64 = \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ perctile-simple-vg.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ dynstats-vg.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ dynstats_reset-vg.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ dynstats_overflow-vg.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ dynstats-json-vg.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ stats-json-vg.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ stats-cee-vg.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ dynstats_prevent_premature_eviction-vg.sh
+
+
+# note that some tests simply USE imptcp, but they also
+# need to be disabled if we do not have this module
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_65 = \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ manyptcp.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_framing_regex.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_framing_regex-oversize.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_large.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp-connection-msg-disabled.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp-connection-msg-received.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp-discard-truncated-msg.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_addtlframedelim.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_conndrop.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_no_octet_counted.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_multi_line.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_spframingfix.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_maxsessions.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_nonProcessingPoller.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_veryLargeOctateCountedMessages.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp-basic-hup.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp-NUL.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp-NUL-rawmsg.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_random.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_hash32.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_hash64.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_replace.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ omfile-sizelimitcmd-many.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ omfile-outchannel-many.sh
+
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_66 = \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imptcp-octet-framing-too-long-vg.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imptcp_conndrop-vg.sh
+
+@ENABLE_FMHASH_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_67 = \
+@ENABLE_FMHASH_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_hash32-vg.sh \
+@ENABLE_FMHASH_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_hash64-vg.sh
+
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_68 = \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_unflatten_arg1_unsuitable.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_unflatten_arg2_invalid.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_unflatten_conflict1.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_unflatten_conflict2.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_unflatten_conflict3.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_unflatten_key_truncated.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_unflatten_non_object.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_unflatten_object.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_unflatten_object_exclamation.sh
+
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_69 = \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_unflatten_arg1_unsuitable-vg.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_unflatten_arg2_invalid-vg.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_unflatten_conflict1-vg.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_unflatten_conflict2-vg.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_unflatten_conflict3-vg.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_unflatten_key_truncated-vg.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_unflatten_non_object-vg.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_unflatten_object-vg.sh \
+@ENABLE_FMUNFLATTEN_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_unflatten_object_exclamation-vg.sh
+
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_70 = \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_all.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_all_2.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_all_empty.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_scheme.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_credential.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_subdomain.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_domain.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_domain_without_tld.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_host.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_tld.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_port.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_resource_path.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_query_string.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_fragment.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ rscript_faup_mozilla_tld.sh
+
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_71 = \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_all_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_all_2_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_all_empty_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_scheme_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_credential_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_subdomain_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_domain_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_domain_without_tld_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_host_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_tld_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_port_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_resource_path_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_query_string_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_fragment_vg.sh \
+@ENABLE_FFAUP_TRUE@@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ rscript_faup_mozilla_tld_vg.sh
+
+@ENABLE_MMPSTRUCDATA_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_72 = \
+@ENABLE_MMPSTRUCDATA_TRUE@@ENABLE_TESTBENCH_TRUE@ mmpstrucdata.sh \
+@ENABLE_MMPSTRUCDATA_TRUE@@ENABLE_TESTBENCH_TRUE@ mmpstrucdata-escaping.sh \
+@ENABLE_MMPSTRUCDATA_TRUE@@ENABLE_TESTBENCH_TRUE@ mmpstrucdata-case.sh
+
+@ENABLE_MMPSTRUCDATA_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_73 = \
+@ENABLE_MMPSTRUCDATA_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmpstrucdata-vg.sh \
+@ENABLE_MMPSTRUCDATA_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmpstrucdata-invalid-vg.sh
+
+@ENABLE_MMRM1STSPACE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_74 = \
+@ENABLE_MMRM1STSPACE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmrm1stspace-basic.sh
+
+@ENABLE_PMNULL_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_75 = \
+@ENABLE_PMNULL_TRUE@@ENABLE_TESTBENCH_TRUE@ pmnull-basic.sh \
+@ENABLE_PMNULL_TRUE@@ENABLE_TESTBENCH_TRUE@ pmnull-withparams.sh
+
+@ENABLE_OMSTDOUT_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_76 = \
+@ENABLE_OMSTDOUT_TRUE@@ENABLE_TESTBENCH_TRUE@ omstdout-basic.sh
+
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_77 = \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmnormalize-basic.sh \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmnormalize-invld-rulebase.sh \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmnormalize-rule.sh \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmnormalize-rule_and_rulebase.sh \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmnormalize-neither_rule_rulebase.sh \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmnormalize-rule_invld-data.sh
+
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_78 = \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ pmnormalize-basic-vg.sh \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ pmnormalize-invld-rulebase-vg.sh \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ pmnormalize-rule-vg.sh \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ pmnormalize-rule_and_rulebase-vg.sh \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ pmnormalize-neither_rule_rulebase-vg.sh \
+@ENABLE_PMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ pmnormalize-rule_invld-data-vg.sh
+
+@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_79 = msgvar-concurrency-array.sh \
+@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ msgvar-concurrency-array-event.tags.sh \
+@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmnormalize_rule_from_string.sh \
+@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmnormalize_rule_from_array.sh \
+@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmnormalize_parsesuccess.sh
+
+@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_80 = \
+@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmnormalize_parsesuccess-vg.sh
+
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_81 = \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmnormalize_regex_defaulted.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmnormalize_regex_disabled.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmnormalize_variable.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmnormalize_tokenized.sh
+
+@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@LOGNORM_REGEX_SUPPORTED_TRUE@am__append_82 = \
+@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@LOGNORM_REGEX_SUPPORTED_TRUE@ mmnormalize_regex.sh
+
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_83 = \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmjsonparse-w-o-cookie.sh \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmjsonparse-w-o-cookie-multi-spaces.sh
+
+@ENABLE_IMPSTATS_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_84 = \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmjsonparse-invalid-containerName.sh \
+@ENABLE_IMPSTATS_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ wtpShutdownAll-assertionFailure.sh
+
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_85 = \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmjsonparse_simple.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp-oversize-message-display.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp-msg-truncation-on-number.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp-msg-truncation-on-number2.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp-maxFrameSize-parameter.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmjsonparse_cim.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmjsonparse_cim2.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ mmjsonparse_localvar.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ json_array_subscripting.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ json_array_looping.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ json_object_looping.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ json_nonarray_looping.sh
+
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_86 = \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmjsonparse_extra_data-vg.sh \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ json_null_array-vg.sh \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ json_object_looping-vg.sh \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ json_array_looping-vg.sh \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ json_object_suicide_in_loop-vg.sh \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ json_null-vg.sh
+
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_87 = \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ stop_when_array_has_element.sh \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ json_null_array.sh \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ json_null.sh \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ json_var_cmpr.sh \
+@ENABLE_MMJSONPARSE_TRUE@@ENABLE_TESTBENCH_TRUE@ json_var_case.sh
+
+@ENABLE_MMDBLOOKUP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_88 = \
+@ENABLE_MMDBLOOKUP_TRUE@@ENABLE_TESTBENCH_TRUE@ mmdb.sh \
+@ENABLE_MMDBLOOKUP_TRUE@@ENABLE_TESTBENCH_TRUE@ mmdb-space.sh \
+@ENABLE_MMDBLOOKUP_TRUE@@ENABLE_TESTBENCH_TRUE@ mmdb-container.sh \
+@ENABLE_MMDBLOOKUP_TRUE@@ENABLE_TESTBENCH_TRUE@ mmdb-container-empty.sh
+
+@ENABLE_MMDBLOOKUP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_89 = \
+@ENABLE_MMDBLOOKUP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmdb-vg.sh \
+@ENABLE_MMDBLOOKUP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmdb-multilevel-vg.sh
+
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_90 = \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-basic.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-input-basic.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-input-2certs.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-basic-verifydepth.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp_conndrop_tls.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_anon_rebind.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_anon_hostname.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_anon_ipv4.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_anon_ipv6.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_certless_clientonly.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_gtls_servercert_gtls_clientanon.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_gtls_servercert_gtls_clientanon_legacy.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_gtls_serveranon_gtls_clientanon.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_priorityString.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_certvalid.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_certvalid_action_level.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_certvalid_expired.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_certvalid_expired_defaultmode.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_certvalid_revoked.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_client_missing_cert.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-no-lstn-startup.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-gtls-x509fingerprint-invld.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-gtls-x509fingerprint.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-gtls-x509name-invld.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-gtls-x509name.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-gtls-x509name-legacy.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-drvr-in-input-basic.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-multi-drvr-basic.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-multi-drvr-basic-parallel.sh
+
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_91 = \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imtcp-tls-basic-vg.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imtcp_conndrop_tls-vg.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ manytcp-too-few-tls-vg.sh
+
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_92 = \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh
+
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_93 = \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-basic.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-input-basic.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-input-2certs.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-basic-tlscommands.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-basic-verifydepth.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-invalid-verifydepth.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_anon_ipv4.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_anon_ipv6.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_anon_rebind.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_anon_ciphers.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_serveranon_ossl_clientanon.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_servercert_ossl_clientanon.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_certvalid.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_certvalid_action_level.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_certvalid_expired.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_certvalid_tlscommand.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_certvalid_ciphers.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_certvalid_revoked.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-x509valid.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-x509name.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-x509fingerprint.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-error-ca.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-error-cert.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-error-key.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ imtcp-tls-ossl-error-key2.sh
+
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_94 = \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imtcp-tls-ossl-basic-vg.sh \
+@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imtcp-tls-ossl-basic-brokenhandshake-vg.sh
+
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_95 = \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_servercert_gtls_clientanon.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_ossl_serveranon_gtls_clientanon.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_gtls_servercert_ossl_clientanon.sh \
+@ENABLE_GNUTLS_TESTS_TRUE@@ENABLE_OPENSSL_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_gtls_serveranon_ossl_clientanon.sh
+
+@ENABLE_OMUXSOCK_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_96 = uxsock_simple.sh
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_97 = sndrcv_relp.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_relp_rebind.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ omrelp_errmsg_no_connect.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-basic.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-basic-oldstyle.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-basic-hup.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-manyconn.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-maxDataSize-error.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-long-msg.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-oversizeMode-truncate.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-oversizeMode-accept.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-invld-tlslib.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-bigmessage.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ omrelp-invld-tlslib.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_relp_dflt_pt.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl-oversizeMsg-log.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl-oversizeMsg-truncate.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl-oversizeMsg-split.sh
+
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_98 = \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_relp_tls.sh \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_relp_tls_certvalid.sh \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_tls_certvalid_action_level.sh \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_relp_tls_prio.sh \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_relp_tls_chainedcert.sh \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ relp_tls_certificate_not_found.sh \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ omrelp_wrong_authmode.sh \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-tls.sh \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-tls-chainedcert.sh \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-tls-mixed-chainedcert.sh \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@ imrelp-tls-mixed-chainedcert2.sh
+
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@@USE_RELPENGINESETTLSCFGCMD_TRUE@am__append_99 = \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@@USE_RELPENGINESETTLSCFGCMD_TRUE@ imrelp-tls-cfgcmd.sh \
+@ENABLE_GNUTLS_TRUE@@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@@USE_RELPENGINESETTLSCFGCMD_TRUE@ sndrcv_relp_tls-cfgcmd.sh
+
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_100 = \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imrelp-basic-vg.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imrelp-sessionbreak-vg.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imrelp-manyconn-vg.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ sndrcv_relp-vg-rcvr.sh \
+@ENABLE_RELP_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ sndrcv_relp-vg-sender.sh
+
+@ENABLE_IMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_101 = \
+@ENABLE_IMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@ imdtls-basic.sh \
+@ENABLE_IMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@ imdtls-basic-tlscommands.sh \
+@ENABLE_IMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@ imdtls-basic-timeout.sh \
+@ENABLE_IMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@ imdtls-error-cert.sh \
+@ENABLE_IMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@ imdtls-sessionbreak.sh
+
+@ENABLE_IMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_102 = \
+@ENABLE_IMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imdtls-basic-vg.sh \
+@ENABLE_IMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imdtls-sessionbreak-vg.sh
+
+@ENABLE_IMDTLS_TRUE@@ENABLE_OMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_103 = \
+@ENABLE_IMDTLS_TRUE@@ENABLE_OMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_dtls_certvalid.sh \
+@ENABLE_IMDTLS_TRUE@@ENABLE_OMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_dtls_anon_ciphers.sh \
+@ENABLE_IMDTLS_TRUE@@ENABLE_OMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_dtls_certvalid_ciphers.sh \
+@ENABLE_IMDTLS_TRUE@@ENABLE_OMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_dtls_certvalid_permitted.sh \
+@ENABLE_IMDTLS_TRUE@@ENABLE_OMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_dtls_certvalid_missing.sh \
+@ENABLE_IMDTLS_TRUE@@ENABLE_OMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_dtls_anon_ciphers.sh
+
+@ENABLE_IMDTLS_TRUE@@ENABLE_OMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_104 = \
+@ENABLE_IMDTLS_TRUE@@ENABLE_OMDTLS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ sndrcv_dtls_certvalid-vg.sh
+
+@ENABLE_OMUDPSPOOF_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_105 = \
+@ENABLE_OMUDPSPOOF_TRUE@@ENABLE_TESTBENCH_TRUE@ omudpspoof_errmsg_no_params.sh \
+@ENABLE_OMUDPSPOOF_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_omudpspoof.sh \
+@ENABLE_OMUDPSPOOF_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_omudpspoof-bigmsg.sh \
+@ENABLE_OMUDPSPOOF_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_omudpspoof_nonstdpt.sh
+
+
+#disabled as array-passing mode is no longer supported: omod-if-array.sh
+# omod-if-array.sh
+# omod-if-array-udp.sh
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_106 = \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ tabescape_dflt.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ tabescape_dflt-udp.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ tabescape_off.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ tabescape_off-udp.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ tabescape_on.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ inputname-imtcp.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ fieldtest.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ fieldtest-udp.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ proprepltest-nolimittag-udp.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ proprepltest-nolimittag.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ proprepltest-rfctag-udp.sh \
+@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ proprepltest-rfctag.sh
+
+@ENABLE_OMRULESET_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_107 = \
+@ENABLE_OMRULESET_TRUE@@ENABLE_TESTBENCH_TRUE@ omruleset.sh \
+@ENABLE_OMRULESET_TRUE@@ENABLE_TESTBENCH_TRUE@ omruleset-queue.sh
+
+@ENABLE_PMDB2DIAG_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_108 = \
+@ENABLE_PMDB2DIAG_TRUE@@ENABLE_TESTBENCH_TRUE@ pmdb2diag_parse.sh
+
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_109 = \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-default.sh \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-default-udp.sh \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-ccoff.sh \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-ccoff-udp.sh \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-ccdefault.sh \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-ccdefault-udp.sh \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-cccstyle.sh \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-cccstyle-udp.sh \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-ccbackslash.sh \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-ccbackslash-udp.sh \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-modoverride.sh \
+@ENABLE_PMSNARE_TRUE@@ENABLE_TESTBENCH_TRUE@ pmsnare-modoverride-udp.sh
+
+@ENABLE_PMLASTMSG_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_110 = \
+@ENABLE_PMLASTMSG_TRUE@@ENABLE_TESTBENCH_TRUE@ pmlastmsg.sh \
+@ENABLE_PMLASTMSG_TRUE@@ENABLE_TESTBENCH_TRUE@ pmlastmsg-udp.sh
+
+
+# random.sh is temporarily disabled as it needs some work
+# to rsyslog core to complete in reasonable time
+#TESTS += random.sh
+@ENABLE_EXTENDED_TESTS_TRUE@@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_111 = \
+@ENABLE_EXTENDED_TESTS_TRUE@@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-basic-2GB-file.sh \
+@ENABLE_EXTENDED_TESTS_TRUE@@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-truncate-2GB-file.sh
+
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_112 = \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-basic.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-basic-legacy.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-discard-truncated-line.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-truncate-line.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-file-not-found-error.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-fileNotFoundError-parameter.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-error-not-repeated.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-truncate.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-truncate-multiple.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-readmode2.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-readmode2-polling.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-readmode2-with-persists-data-during-stop.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-readmode2-with-persists.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-endregex.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-endregex-save-lf.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-endregex-save-lf-persist.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-endregex-timeout-none-polling.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-endregex-timeout-polling.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-endregex-timeout.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-endregex-timeout-none.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-endregex-timeout-with-shutdown.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-endregex-timeout-with-shutdown-polling.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-endmsg.regex.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-escapelf.replacement.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-escapelf.replacement-empty.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-statefile-no-file_id.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-statefile-no-file_id-TO-file_id.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-statefile-directory.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-statefile-delete.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-statefile-no-delete.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-persist-state-1.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-freshStartTail1.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-freshStartTail2.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-freshStartTail3.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-wildcards.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-wildcards-dirs.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-wildcards-dirs2.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-wildcards-dirs-multi.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-wildcards-dirs-multi2.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-wildcards-dirs-multi3.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-wildcards-dirs-multi4.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-wildcards-dirs-multi5.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-wildcards-dirs-multi5-polling.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-old-state-file.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-rename-while-stopped.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-rename.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-symlink.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-symlink-multi.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-symlink-ext-tmp-dir-tree.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-logrotate.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-logrotate-async.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-logrotate-multiple.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-logrotate-copytruncate.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-logrotate-nocopytruncate.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-growing-file-id.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-ignore-old-file-1.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-ignore-old-file-2.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-ignore-old-file-3.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-ignore-old-file-4.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-ignore-old-file-5.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-ignore-old-file-6.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-ignore-old-file-7.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ glbl-oversizeMsg-truncate-imfile.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ config_enabled-on.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ config_enabled-off.sh
+
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_113 = \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@ imfile-endmsg.regex-with-example.sh
+
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_114 = \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imfile-basic-vg.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imfile-endregex-vg.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imfile-endmsg.regex-vg.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imfile-readmode0-vg.sh \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imfile-readmode2-vg.sh
+
+@ENABLE_HELGRIND_TRUE@@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_115 = \
+@ENABLE_HELGRIND_TRUE@@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imfile-basic-vgthread.sh
+
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_116 = \
+@ENABLE_IMFILE_TESTS_TRUE@@ENABLE_MMNORMALIZE_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imfile-endmsg.regex-with-example-vg.sh
+
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_117 = \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_no_params.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_glob_not_regular.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_glob_dir_fake.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_glob_dir_not_dir.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_regex.match.reject.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_regex.match.rename.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_regex.nomatch.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_not_supported1.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_not_supported2.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_not_supported3.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_delete_params.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_errmsg_rename_params.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_delete_success.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_delete_structdata.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_rename_success.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_delete_toolarge.sh \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@ imbatchreport_rename_toolarge.sh
+
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_118 = \
+@ENABLE_IMBATCHREPORT_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imbatchreport_errmsg_no_params-vg.sh
+
+@ENABLE_OMTCL_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_119 = \
+@ENABLE_OMTCL_TRUE@@ENABLE_TESTBENCH_TRUE@ omtcl.sh
+
+@ENABLE_MMTAGHOSTNAME_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_120 = \
+@ENABLE_MMTAGHOSTNAME_TRUE@@ENABLE_TESTBENCH_TRUE@ mmtaghostname_tag.sh \
+@ENABLE_MMTAGHOSTNAME_TRUE@@ENABLE_TESTBENCH_TRUE@ mmtaghostname_server.sh
+
+@ENABLE_IMFILE_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_MMKUBERNETES_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_121 = \
+@ENABLE_IMFILE_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_MMKUBERNETES_TRUE@@ENABLE_TESTBENCH_TRUE@ mmkubernetes-basic.sh \
+@ENABLE_IMFILE_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_MMKUBERNETES_TRUE@@ENABLE_TESTBENCH_TRUE@ mmkubernetes-cache-expire.sh
+
+@ENABLE_IMFILE_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_MMKUBERNETES_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_122 = \
+@ENABLE_IMFILE_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_MMKUBERNETES_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmkubernetes-basic-vg.sh \
+@ENABLE_IMFILE_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_MMJSONPARSE_TRUE@@ENABLE_MMKUBERNETES_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mmkubernetes-cache-expire-vg.sh
+
+@ENABLE_IMTUXEDOULOG_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_123 = \
+@ENABLE_IMTUXEDOULOG_TRUE@@ENABLE_TESTBENCH_TRUE@ imtuxedoulog_errmsg_no_params.sh \
+@ENABLE_IMTUXEDOULOG_TRUE@@ENABLE_TESTBENCH_TRUE@ imtuxedoulog_data.sh
+
+@ENABLE_IMTUXEDOULOG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_124 = \
+@ENABLE_IMTUXEDOULOG_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ imtuxedoulog_errmsg_no_params-vg.sh
+
+@ENABLE_OMAMQP1_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_125 = \
+@ENABLE_OMAMQP1_TRUE@@ENABLE_TESTBENCH_TRUE@ omamqp1-basic.sh
+
+@ENABLE_OMAMQP1_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@am__append_126 = \
+@ENABLE_OMAMQP1_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ omamqp1-basic-vg.sh
+
+@ENABLE_GNUTLS_TRUE@am__append_127 = $(GNUTLS_CFLAGS)
+@ENABLE_GNUTLS_TRUE@am__append_128 = $(GNUTLS_CFLAGS)
+@ENABLE_GNUTLS_TRUE@am__append_129 = $(GNUTLS_LIBS)
+@ENABLE_OPENSSL_TRUE@am__append_130 = $(OPENSSL_CFLAGS)
+@ENABLE_OPENSSL_TRUE@am__append_131 = $(OPENSSL_CFLAGS)
+@ENABLE_OPENSSL_TRUE@am__append_132 = $(OPENSSL_LIBS)
+subdir = tests
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \
+ $(top_srcdir)/m4/atomic_operations.m4 \
+ $(top_srcdir)/m4/atomic_operations_64bit.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = set-envvars
+CONFIG_CLEAN_VPATH_FILES =
+@ENABLE_IMJOURNAL_TRUE@@ENABLE_JOURNAL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__EXEEXT_1 = journal_print$(EXEEXT)
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@am__EXEEXT_2 = miniamqpsrvr$(EXEEXT)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(pkglibdir)"
+LTLIBRARIES = $(pkglib_LTLIBRARIES)
+liboverride_getaddrinfo_la_LIBADD =
+am__liboverride_getaddrinfo_la_SOURCES_DIST = override_getaddrinfo.c
+@ENABLE_TESTBENCH_TRUE@am_liboverride_getaddrinfo_la_OBJECTS = liboverride_getaddrinfo_la-override_getaddrinfo.lo
+liboverride_getaddrinfo_la_OBJECTS = \
+ $(am_liboverride_getaddrinfo_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+liboverride_getaddrinfo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(liboverride_getaddrinfo_la_CFLAGS) $(CFLAGS) \
+ $(liboverride_getaddrinfo_la_LDFLAGS) $(LDFLAGS) -o $@
+@ENABLE_TESTBENCH_TRUE@am_liboverride_getaddrinfo_la_rpath = -rpath \
+@ENABLE_TESTBENCH_TRUE@ $(pkglibdir)
+liboverride_gethostname_la_LIBADD =
+am__liboverride_gethostname_la_SOURCES_DIST = override_gethostname.c
+@ENABLE_TESTBENCH_TRUE@am_liboverride_gethostname_la_OBJECTS = liboverride_gethostname_la-override_gethostname.lo
+liboverride_gethostname_la_OBJECTS = \
+ $(am_liboverride_gethostname_la_OBJECTS)
+liboverride_gethostname_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(liboverride_gethostname_la_CFLAGS) $(CFLAGS) \
+ $(liboverride_gethostname_la_LDFLAGS) $(LDFLAGS) -o $@
+@ENABLE_TESTBENCH_TRUE@am_liboverride_gethostname_la_rpath = -rpath \
+@ENABLE_TESTBENCH_TRUE@ $(pkglibdir)
+liboverride_gethostname_nonfqdn_la_LIBADD =
+am__liboverride_gethostname_nonfqdn_la_SOURCES_DIST = \
+ override_gethostname_nonfqdn.c
+@ENABLE_TESTBENCH_TRUE@am_liboverride_gethostname_nonfqdn_la_OBJECTS = liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.lo
+liboverride_gethostname_nonfqdn_la_OBJECTS = \
+ $(am_liboverride_gethostname_nonfqdn_la_OBJECTS)
+liboverride_gethostname_nonfqdn_la_LINK = $(LIBTOOL) $(AM_V_lt) \
+ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
+ $(CCLD) $(liboverride_gethostname_nonfqdn_la_CFLAGS) $(CFLAGS) \
+ $(liboverride_gethostname_nonfqdn_la_LDFLAGS) $(LDFLAGS) -o $@
+@ENABLE_TESTBENCH_TRUE@am_liboverride_gethostname_nonfqdn_la_rpath = \
+@ENABLE_TESTBENCH_TRUE@ -rpath $(pkglibdir)
+check_relpEngineVersion_SOURCES = check_relpEngineVersion.c
+check_relpEngineVersion_OBJECTS = check_relpEngineVersion.$(OBJEXT)
+check_relpEngineVersion_LDADD = $(LDADD)
+am_chkseq_OBJECTS = chkseq.$(OBJEXT)
+chkseq_OBJECTS = $(am_chkseq_OBJECTS)
+chkseq_LDADD = $(LDADD)
+am_diagtalker_OBJECTS = diagtalker.$(OBJEXT)
+diagtalker_OBJECTS = $(am_diagtalker_OBJECTS)
+am__DEPENDENCIES_1 =
+diagtalker_DEPENDENCIES = $(am__DEPENDENCIES_1)
+have_relpEngineSetTLSLibByName_SOURCES = \
+ have_relpEngineSetTLSLibByName.c
+have_relpEngineSetTLSLibByName_OBJECTS = \
+ have_relpEngineSetTLSLibByName.$(OBJEXT)
+have_relpEngineSetTLSLibByName_LDADD = $(LDADD)
+have_relpSrvSetOversizeMode_SOURCES = have_relpSrvSetOversizeMode.c
+have_relpSrvSetOversizeMode_OBJECTS = \
+ have_relpSrvSetOversizeMode.$(OBJEXT)
+have_relpSrvSetOversizeMode_LDADD = $(LDADD)
+have_relpSrvSetTlsConfigCmd_SOURCES = have_relpSrvSetTlsConfigCmd.c
+have_relpSrvSetTlsConfigCmd_OBJECTS = \
+ have_relpSrvSetTlsConfigCmd.$(OBJEXT)
+have_relpSrvSetTlsConfigCmd_LDADD = $(LDADD)
+am_inputfilegen_OBJECTS = inputfilegen.$(OBJEXT)
+inputfilegen_OBJECTS = $(am_inputfilegen_OBJECTS)
+inputfilegen_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_journal_print_OBJECTS = journal_print-journal_print.$(OBJEXT)
+journal_print_OBJECTS = $(am_journal_print_OBJECTS)
+journal_print_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_mangle_qi_OBJECTS = mangle_qi.$(OBJEXT)
+mangle_qi_OBJECTS = $(am_mangle_qi_OBJECTS)
+mangle_qi_LDADD = $(LDADD)
+am__miniamqpsrvr_SOURCES_DIST = miniamqpsrvr.c
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@am_miniamqpsrvr_OBJECTS = miniamqpsrvr-miniamqpsrvr.$(OBJEXT)
+miniamqpsrvr_OBJECTS = $(am_miniamqpsrvr_OBJECTS)
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@miniamqpsrvr_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@ $(am__DEPENDENCIES_1)
+am_minitcpsrv_OBJECTS = minitcpsrvr.$(OBJEXT)
+minitcpsrv_OBJECTS = $(am_minitcpsrv_OBJECTS)
+minitcpsrv_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_msleep_OBJECTS = msleep.$(OBJEXT)
+msleep_OBJECTS = $(am_msleep_OBJECTS)
+msleep_LDADD = $(LDADD)
+am_omrelp_dflt_port_OBJECTS = omrelp_dflt_port.$(OBJEXT)
+omrelp_dflt_port_OBJECTS = $(am_omrelp_dflt_port_OBJECTS)
+omrelp_dflt_port_LDADD = $(LDADD)
+am_ourtail_OBJECTS = ourtail.$(OBJEXT)
+ourtail_OBJECTS = $(am_ourtail_OBJECTS)
+ourtail_LDADD = $(LDADD)
+am_randomgen_OBJECTS = randomgen.$(OBJEXT)
+randomgen_OBJECTS = $(am_randomgen_OBJECTS)
+randomgen_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_syslog_caller_OBJECTS = syslog_caller-syslog_caller.$(OBJEXT)
+syslog_caller_OBJECTS = $(am_syslog_caller_OBJECTS)
+syslog_caller_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_tcpflood_OBJECTS = tcpflood-tcpflood.$(OBJEXT)
+tcpflood_OBJECTS = $(am_tcpflood_OBJECTS)
+@ENABLE_GNUTLS_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
+@ENABLE_OPENSSL_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1)
+tcpflood_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_3)
+tcpflood_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(tcpflood_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_test_id_OBJECTS = test_id.$(OBJEXT)
+test_id_OBJECTS = $(am_test_id_OBJECTS)
+test_id_LDADD = $(LDADD)
+am_uxsockrcvr_OBJECTS = uxsockrcvr.$(OBJEXT)
+uxsockrcvr_OBJECTS = $(am_uxsockrcvr_OBJECTS)
+uxsockrcvr_DEPENDENCIES = $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/check_relpEngineVersion.Po \
+ ./$(DEPDIR)/chkseq.Po ./$(DEPDIR)/diagtalker.Po \
+ ./$(DEPDIR)/have_relpEngineSetTLSLibByName.Po \
+ ./$(DEPDIR)/have_relpSrvSetOversizeMode.Po \
+ ./$(DEPDIR)/have_relpSrvSetTlsConfigCmd.Po \
+ ./$(DEPDIR)/inputfilegen.Po \
+ ./$(DEPDIR)/journal_print-journal_print.Po \
+ ./$(DEPDIR)/liboverride_getaddrinfo_la-override_getaddrinfo.Plo \
+ ./$(DEPDIR)/liboverride_gethostname_la-override_gethostname.Plo \
+ ./$(DEPDIR)/liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.Plo \
+ ./$(DEPDIR)/mangle_qi.Po \
+ ./$(DEPDIR)/miniamqpsrvr-miniamqpsrvr.Po \
+ ./$(DEPDIR)/minitcpsrvr.Po ./$(DEPDIR)/msleep.Po \
+ ./$(DEPDIR)/omrelp_dflt_port.Po ./$(DEPDIR)/ourtail.Po \
+ ./$(DEPDIR)/randomgen.Po \
+ ./$(DEPDIR)/syslog_caller-syslog_caller.Po \
+ ./$(DEPDIR)/tcpflood-tcpflood.Po ./$(DEPDIR)/test_id.Po \
+ ./$(DEPDIR)/uxsockrcvr.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(liboverride_getaddrinfo_la_SOURCES) \
+ $(liboverride_gethostname_la_SOURCES) \
+ $(liboverride_gethostname_nonfqdn_la_SOURCES) \
+ check_relpEngineVersion.c $(chkseq_SOURCES) \
+ $(diagtalker_SOURCES) have_relpEngineSetTLSLibByName.c \
+ have_relpSrvSetOversizeMode.c have_relpSrvSetTlsConfigCmd.c \
+ $(inputfilegen_SOURCES) $(journal_print_SOURCES) \
+ $(mangle_qi_SOURCES) $(miniamqpsrvr_SOURCES) \
+ $(minitcpsrv_SOURCES) $(msleep_SOURCES) \
+ $(omrelp_dflt_port_SOURCES) $(ourtail_SOURCES) \
+ $(randomgen_SOURCES) $(syslog_caller_SOURCES) \
+ $(tcpflood_SOURCES) $(test_id_SOURCES) $(uxsockrcvr_SOURCES)
+DIST_SOURCES = $(am__liboverride_getaddrinfo_la_SOURCES_DIST) \
+ $(am__liboverride_gethostname_la_SOURCES_DIST) \
+ $(am__liboverride_gethostname_nonfqdn_la_SOURCES_DIST) \
+ check_relpEngineVersion.c $(chkseq_SOURCES) \
+ $(diagtalker_SOURCES) have_relpEngineSetTLSLibByName.c \
+ have_relpSrvSetOversizeMode.c have_relpSrvSetTlsConfigCmd.c \
+ $(inputfilegen_SOURCES) $(journal_print_SOURCES) \
+ $(mangle_qi_SOURCES) $(am__miniamqpsrvr_SOURCES_DIST) \
+ $(minitcpsrv_SOURCES) $(msleep_SOURCES) \
+ $(omrelp_dflt_port_SOURCES) $(ourtail_SOURCES) \
+ $(randomgen_SOURCES) $(syslog_caller_SOURCES) \
+ $(tcpflood_SOURCES) $(test_id_SOURCES) $(uxsockrcvr_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.sh.log=.log)
+SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+SH_LOG_COMPILE = $(SH_LOG_COMPILER) $(AM_SH_LOG_FLAGS) $(SH_LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/set-envvars.in \
+ $(top_srcdir)/depcomp $(top_srcdir)/test-driver README
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APU_CFLAGS = @APU_CFLAGS@
+APU_LIBS = @APU_LIBS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CIVETWEB_LIBS = @CIVETWEB_LIBS@
+CONF_FILE_PATH = @CONF_FILE_PATH@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CURL_CFLAGS = @CURL_CFLAGS@
+CURL_LIBS = @CURL_LIBS@
+CYGPATH_W = @CYGPATH_W@
+CZMQ_CFLAGS = @CZMQ_CFLAGS@
+CZMQ_LIBS = @CZMQ_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FAUP_LIBS = @FAUP_LIBS@
+FGREP = @FGREP@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_LIBS = @GLIB_LIBS@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GSS_LIBS = @GSS_LIBS@
+GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@
+GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@
+HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@
+HIREDIS_CFLAGS = @HIREDIS_CFLAGS@
+HIREDIS_LIBS = @HIREDIS_LIBS@
+IMUDP_LIBS = @IMUDP_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IP = @IP@
+JAVA = @JAVA@
+JAVAC = @JAVAC@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@
+LIBCAPNG_LIBS = @LIBCAPNG_LIBS@
+LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@
+LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@
+LIBDBI_CFLAGS = @LIBDBI_CFLAGS@
+LIBDBI_LIBS = @LIBDBI_LIBS@
+LIBESTR_CFLAGS = @LIBESTR_CFLAGS@
+LIBESTR_LIBS = @LIBESTR_LIBS@
+LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@
+LIBEVENT_LIBS = @LIBEVENT_LIBS@
+LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@
+LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@
+LIBLOGGING_LIBS = @LIBLOGGING_LIBS@
+LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@
+LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@
+LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@
+LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@
+LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@
+LIBLZ4_LIBS = @LIBLZ4_LIBS@
+LIBM = @LIBM@
+LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@
+LIBMONGOC_LIBS = @LIBMONGOC_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@
+LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@
+LIBS = @LIBS@
+LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@
+LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@
+LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@
+LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUUID_CFLAGS = @LIBUUID_CFLAGS@
+LIBUUID_LIBS = @LIBUUID_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MYSQL_CFLAGS = @MYSQL_CFLAGS@
+MYSQL_CONFIG = @MYSQL_CONFIG@
+MYSQL_LIBS = @MYSQL_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PGSQL_CFLAGS = @PGSQL_CFLAGS@
+PGSQL_LIBS = @PGSQL_LIBS@
+PG_CONFIG = @PG_CONFIG@
+PID_FILE_PATH = @PID_FILE_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PROTON_CFLAGS = @PROTON_CFLAGS@
+PROTON_LIBS = @PROTON_LIBS@
+PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@
+PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@
+PTHREADS_CFLAGS = @PTHREADS_CFLAGS@
+PTHREADS_LIBS = @PTHREADS_LIBS@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@
+RABBITMQ_LIBS = @RABBITMQ_LIBS@
+RANLIB = @RANLIB@
+READLINK = @READLINK@
+REDIS = @REDIS@
+RELP_CFLAGS = @RELP_CFLAGS@
+RELP_LIBS = @RELP_LIBS@
+RSRT_CFLAGS = @RSRT_CFLAGS@
+RSRT_CFLAGS1 = @RSRT_CFLAGS1@
+RSRT_LIBS = @RSRT_LIBS@
+RSRT_LIBS1 = @RSRT_LIBS1@
+RST2MAN = @RST2MAN@
+RT_LIBS = @RT_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMP_CFLAGS = @SNMP_CFLAGS@
+SNMP_LIBS = @SNMP_LIBS@
+SOL_LIBS = @SOL_LIBS@
+STRIP = @STRIP@
+TCL_BIN_DIR = @TCL_BIN_DIR@
+TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@
+TCL_LIB_FILE = @TCL_LIB_FILE@
+TCL_LIB_FLAG = @TCL_LIB_FLAG@
+TCL_LIB_SPEC = @TCL_LIB_SPEC@
+TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@
+TCL_SRC_DIR = @TCL_SRC_DIR@
+TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@
+TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@
+TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
+TCL_VERSION = @TCL_VERSION@
+UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@
+UDPSPOOF_LIBS = @UDPSPOOF_LIBS@
+VALGRIND = @VALGRIND@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_LDFLAGS = @WARN_LDFLAGS@
+WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@
+WGET = @WGET@
+YACC = @YACC@
+YACC_FOUND = @YACC_FOUND@
+YFLAGS = @YFLAGS@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+ZSTD_CFLAGS = @ZSTD_CFLAGS@
+ZSTD_LIBS = @ZSTD_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+moddirs = @moddirs@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+TEST_EXTENSIONS = .sh
+@ENABLE_TESTBENCH_TRUE@CLEANFILES = *_*.conf rsyslog*.started \
+@ENABLE_TESTBENCH_TRUE@ work-*.conf rsyslog.random.data \
+@ENABLE_TESTBENCH_TRUE@ rsyslog*.pid.save xlate*.lkp_tbl log \
+@ENABLE_TESTBENCH_TRUE@ log* *.log work test-spool test-logdir \
+@ENABLE_TESTBENCH_TRUE@ stat-file1 rsyslog.pipe rsyslog.input.* \
+@ENABLE_TESTBENCH_TRUE@ rsyslog.input rsyslog.input.* \
+@ENABLE_TESTBENCH_TRUE@ imfile-state:* omkafka-failed.data \
+@ENABLE_TESTBENCH_TRUE@ rsyslog.input-symlink.log \
+@ENABLE_TESTBENCH_TRUE@ rsyslog-link.*.log targets HOSTNAME \
+@ENABLE_TESTBENCH_TRUE@ rstb_* zookeeper.pid tmp.qi nocert \
+@ENABLE_TESTBENCH_TRUE@ IN_AUTO_DEBUG
+# IN_AUTO_DEBUG should be deleted each time make check is run, but
+# there exists no such hook. Se we at least delete it on make clean.
+@ENABLE_TESTBENCH_TRUE@pkglib_LTLIBRARIES = \
+@ENABLE_TESTBENCH_TRUE@ liboverride_gethostname.la \
+@ENABLE_TESTBENCH_TRUE@ liboverride_gethostname_nonfqdn.la \
+@ENABLE_TESTBENCH_TRUE@ liboverride_getaddrinfo.la
+@ENABLE_TESTBENCH_TRUE@liboverride_gethostname_la_SOURCES = override_gethostname.c
+@ENABLE_TESTBENCH_TRUE@liboverride_gethostname_la_CFLAGS =
+@ENABLE_TESTBENCH_TRUE@liboverride_gethostname_la_LDFLAGS = -avoid-version -shared
+@ENABLE_TESTBENCH_TRUE@liboverride_gethostname_nonfqdn_la_SOURCES = override_gethostname_nonfqdn.c
+@ENABLE_TESTBENCH_TRUE@liboverride_gethostname_nonfqdn_la_CFLAGS =
+@ENABLE_TESTBENCH_TRUE@liboverride_gethostname_nonfqdn_la_LDFLAGS = -avoid-version -shared
+@ENABLE_TESTBENCH_TRUE@liboverride_getaddrinfo_la_SOURCES = override_getaddrinfo.c
+@ENABLE_TESTBENCH_TRUE@liboverride_getaddrinfo_la_CFLAGS =
+@ENABLE_TESTBENCH_TRUE@liboverride_getaddrinfo_la_LDFLAGS = -avoid-version -shared
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@miniamqpsrvr_SOURCES = miniamqpsrvr.c
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@miniamqpsrvr_CPPFLAGS = $(PTHREADS_CFLAGS) $(RABBITMQ_CFLAGS) $(RSRT_CFLAGS)
+@ENABLE_OMRABBITMQ_TRUE@@ENABLE_TESTBENCH_TRUE@miniamqpsrvr_LDADD = $(SOL_LIBS) $(PTHREADS_LIBS)
+TESTS_ENVIRONMENT = \
+ RSYSLOG_MODDIR='$(abs_top_builddir)'/runtime/.libs/ \
+ TOP_BUILDDIR='$(top_builddir)' \
+ TESTTOOL_DIR='$(abs_top_builddir)/tests'
+test_files = testbench.h runtime-dummy.c
+DISTCLEANFILES = rsyslog.pid
+EXTRA_DIST = \
+ set-envvars.in \
+ urlencode.py \
+ dnscache-TTL-0.sh \
+ dnscache-TTL-0-vg.sh \
+ loadbalance.sh \
+ smtradfile.sh \
+ smtradfile-vg.sh \
+ immark.sh \
+ immark-inputname.sh \
+ immark-ruleset.sh \
+ immark-ruleset-custom-msg.sh \
+ operatingstate-basic.sh \
+ operatingstate-empty.sh \
+ operatingstate-unclean.sh \
+ internal-errmsg-memleak-vg.sh \
+ glbl-ruleset-queue-defaults.sh \
+ glbl-internalmsg_severity-info-shown.sh \
+ glbl-internalmsg_severity-debug-shown.sh \
+ glbl-internalmsg_severity-debug-not_shown.sh \
+ glbl-oversizeMsg-log-vg.sh \
+ config_enabled-on.sh \
+ config_enabled-off.sh \
+ empty-app-name.sh \
+ empty-hostname.sh \
+ func-substring-invld-startpos.sh \
+ func-substring-invld-startpos-vg.sh \
+ func-substring-large-endpos.sh \
+ func-substring-large-neg-endpos.sh \
+ func-substring-relative-endpos.sh \
+ hostname-with-slash-pmrfc5424.sh \
+ hostname-with-slash-pmrfc3164.sh \
+ pmrfc3164-msgFirstSpace.sh \
+ pmrfc3164-AtSignsInHostname.sh \
+ pmrfc3164-AtSignsInHostname_off.sh \
+ pmrfc3164-tagEndingByColon.sh \
+ pmrfc3164-defaultTag.sh \
+ pmrfc3164-json.sh \
+ hostname-with-slash-dflt-invld.sh \
+ hostname-with-slash-dflt-slash-valid.sh \
+ glbl-umask.sh \
+ glbl-unloadmodules.sh \
+ glbl-invld-param.sh \
+ glbl_setenv_2_vars.sh \
+ glbl_setenv_err.sh \
+ glbl_setenv_err_too_long.sh \
+ glbl_setenv.sh \
+ imtuxedoulog_errmsg_no_params.sh \
+ imtuxedoulog_data.sh \
+ imtuxedoulog_errmsg_no_params-vg.sh \
+ pmdb2diag_parse.sh \
+ mmtaghostname_tag.sh \
+ mmtaghostname_server.sh \
+ imbatchreport_errmsg_no_params.sh \
+ imbatchreport_errmsg_glob_not_regular.sh \
+ imbatchreport_errmsg_glob_dir_fake.sh \
+ imbatchreport_errmsg_glob_dir_not_dir.sh \
+ imbatchreport_errmsg_regex.match.reject.sh \
+ imbatchreport_errmsg_regex.match.rename.sh \
+ imbatchreport_errmsg_regex.nomatch.sh \
+ imbatchreport_errmsg_not_supported1.sh \
+ imbatchreport_errmsg_not_supported2.sh \
+ imbatchreport_errmsg_not_supported3.sh \
+ imbatchreport_errmsg_delete_params.sh \
+ imbatchreport_errmsg_rename_params.sh \
+ imbatchreport_delete_success.sh \
+ imbatchreport_delete_structdata.sh \
+ imbatchreport_rename_success.sh \
+ imbatchreport_delete_toolarge.sh \
+ imbatchreport_rename_toolarge.sh \
+ imbatchreport_errmsg_no_params-vg.sh \
+ mmexternal-SegFault.sh \
+ mmexternal-SegFault-empty-jroot-vg.sh \
+ testsuites/mmexternal-SegFault-mm-python.py \
+ mmexternal-InvldProg-vg.sh \
+ nested-call-shutdown.sh \
+ 1.rstest 2.rstest 3.rstest err1.rstest \
+ config_multiple_include.sh \
+ testsuites/include-std1-omfile-action.conf \
+ testsuites/include-std2-omfile-action.conf \
+ invalid_nested_include.sh \
+ validation-run.sh \
+ tls-certs/ca-key.pem \
+ tls-certs/ca.pem \
+ tls-certs/cert.pem \
+ tls-certs/certchained.pem \
+ tls-certs/key.pem \
+ tls-certs/ca-fail.pem \
+ tls-certs/cert-fail.pem \
+ tls-certs/key-fail.pem \
+ testsuites/x.509/ca.srl \
+ testsuites/x.509/client-cert-new.pem \
+ testsuites/x.509/client-new.csr \
+ testsuites/x.509/client-revoked-key.pem \
+ testsuites/x.509/client-revoked-valid.pem \
+ testsuites/x.509/client-revoked.csr \
+ testsuites/x.509/client-revoked.pem \
+ testsuites/x.509/crl.pem \
+ testsuites/x.509/index.txt \
+ testsuites/x.509/index.txt.attr \
+ testsuites/x.509/newcerts/01.pem \
+ testsuites/x.509/newcerts/02.pem \
+ testsuites/x.509/newcerts/03.pem \
+ testsuites/x.509/newcerts/04.pem \
+ testsuites/x.509/openssl-cmds.sh \
+ testsuites/x.509/openssl.cnf \
+ testsuites/x.509/serial \
+ testsuites/x.509/ca.pem \
+ testsuites/x.509/ca-key.pem \
+ testsuites/x.509/client-cert.pem \
+ testsuites/x.509/client-key.pem \
+ testsuites/x.509/machine-cert.pem \
+ testsuites/x.509/machine-key.pem \
+ testsuites/x.509/client-expired-cert.pem \
+ testsuites/x.509/client-expired-key.pem \
+ cfg.sh \
+ cfg1.cfgtest \
+ cfg1.testin \
+ cfg2.cfgtest \
+ cfg2.testin \
+ cfg3.cfgtest \
+ cfg3.testin \
+ cfg4.cfgtest \
+ cfg4.testin \
+ DevNull.cfgtest \
+ err1.rstest \
+ NoExistFile.cfgtest \
+ tcp_forwarding_tpl.sh \
+ tcp_forwarding_ns_tpl.sh \
+ tcp_forwarding_dflt_tpl.sh \
+ tcp_forwarding_retries.sh \
+ mainq_actq_DA.sh \
+ queue_warnmsg-oversize.sh \
+ queue-minbatch.sh \
+ queue-minbatch-queuefull.sh \
+ queue-direct-with-no-params.sh \
+ queue-direct-with-params-given.sh \
+ killrsyslog.sh \
+ parsertest-parse1.sh \
+ parsertest-parse1-udp.sh \
+ parsertest-parse2.sh \
+ parsertest-parse2-udp.sh \
+ parsertest-parse_8bit_escape.sh \
+ parsertest-parse_8bit_escape-udp.sh \
+ parsertest-parse3.sh \
+ parsertest-parse3-udp.sh \
+ parsertest-parse_invld_regex.sh \
+ parsertest-parse_invld_regex-udp.sh \
+ parsertest-parse-3164-buggyday.sh \
+ parsertest-parse-3164-buggyday-udp.sh \
+ parsertest-parse-nodate.sh \
+ parsertest-parse-nodate-udp.sh \
+ parsertest-snare_ccoff_udp.sh \
+ parsertest-snare_ccoff_udp2.sh \
+ fieldtest.sh \
+ fieldtest-udp.sh \
+ proprepltest-nolimittag-udp.sh \
+ proprepltest-nolimittag.sh \
+ proprepltest-rfctag-udp.sh \
+ proprepltest-rfctag.sh \
+ timestamp-3164.sh \
+ timestamp-3339.sh \
+ timestamp-isoweek.sh \
+ timestamp-mysql.sh \
+ timestamp-pgsql.sh \
+ timestamp-subseconds.sh \
+ rsf_getenv.sh \
+ diskq-rfc5424.sh \
+ rfc5424parser-sp_at_msg_start.sh \
+ diskqueue-full.sh \
+ diskqueue-fail.sh \
+ diskqueue.sh \
+ diskqueue-non-unique-prefix.sh \
+ arrayqueue.sh \
+ include-obj-text-from-file.sh \
+ include-obj-text-from-file-noexist.sh \
+ include-obj-outside-control-flow-vg.sh \
+ include-obj-in-if-vg.sh \
+ include-obj-text-vg.sh \
+ config_output-o-option.sh \
+ rscript-config_enable-off-vg.sh \
+ rscript-config_enable-on.sh \
+ rscript_http_request.sh \
+ rscript_http_request-vg.sh \
+ rscript_bare_var_root.sh \
+ rscript_bare_var_root-empty.sh \
+ rscript_contains.sh \
+ rscript_ipv42num.sh \
+ rscript_field.sh \
+ rscript_field-vg.sh \
+ rscript_stop.sh \
+ rscript_stop2.sh \
+ stop.sh \
+ rscript_le.sh \
+ rscript_le_var.sh \
+ rscript_ge.sh \
+ rscript_ge_var.sh \
+ rscript_lt.sh \
+ rscript_lt_var.sh \
+ rscript_gt.sh \
+ rscript_gt_var.sh \
+ rscript_ne.sh \
+ rscript_ne_var.sh \
+ rscript_number_comparison_LE.sh \
+ rscript_number_comparison_LE-vg.sh \
+ rscript_number_comparison_LT.sh \
+ rscript_compare_str-numstr.sh \
+ rscript_compare_str-num.sh \
+ rscript_compare_numstr-str.sh \
+ rscript_compare_num-str.sh \
+ rscript_compare_numstr-numstr.sh \
+ rscript_compare_numstr-num.sh \
+ rscript_compare_num-numstr.sh \
+ rscript_compare_num-num.sh \
+ rscript_compare_str-str.sh \
+ rscript_compare_str-str-vg.sh \
+ rscript_compare_str-num-vg.sh \
+ rscript_compare_str-numstr-vg.sh \
+ rscript_compare_num-str-vg.sh \
+ rscript_compare_numstr-str-vg.sh \
+ rscript_compare_numstr-num-vg.sh \
+ rscript_compare_numstr-numstr-vg.sh \
+ rscript_compare_num-num-vg.sh \
+ rscript_compare_num-numstr-vg.sh \
+ rscript_compare-common.sh \
+ rscript_num2ipv4.sh \
+ rscript_int2Hex.sh \
+ rscript_trim.sh \
+ rscript_substring.sh \
+ rscript_format_time.sh \
+ rscript_parse_time.sh \
+ rscript_parse_time_get-ts.py \
+ rscript_is_time.sh \
+ rscript_script_error.sh \
+ rscript_parse_json.sh \
+ rscript_parse_json-vg.sh \
+ rscript_backticks-vg.sh \
+ rscript_backticks_empty_envvar-vg.sh \
+ rscript_previous_action_suspended.sh \
+ rscript_str2num_negative.sh \
+ rscript_exists-yes.sh \
+ rscript_exists-yes2.sh \
+ rscript_exists-not1.sh \
+ rscript_exists-not2.sh \
+ rscript_exists-not3.sh \
+ rscript_exists-not4.sh \
+ rscript_unflatten_arg1_unsuitable.sh \
+ rscript_unflatten_arg2_invalid.sh \
+ rscript_unflatten_conflict1.sh \
+ rscript_unflatten_conflict2.sh \
+ rscript_unflatten_conflict3.sh \
+ rscript_unflatten_key_truncated.sh \
+ rscript_unflatten_non_object.sh \
+ rscript_unflatten_object_exclamation.sh \
+ rscript_unflatten_object.sh \
+ rscript_unflatten_arg1_unsuitable-vg.sh \
+ rscript_unflatten_arg2_invalid-vg.sh \
+ rscript_unflatten_conflict1-vg.sh \
+ rscript_unflatten_conflict2-vg.sh \
+ rscript_unflatten_conflict3-vg.sh \
+ rscript_unflatten_key_truncated-vg.sh \
+ rscript_unflatten_non_object-vg.sh \
+ rscript_unflatten_object_exclamation-vg.sh \
+ rscript_unflatten_object-vg.sh \
+ rscript_get_property.sh \
+ rscript_get_property-vg.sh \
+ rs-cnum.sh \
+ rs-int2hex.sh \
+ rs-substring.sh \
+ omsnmp_errmsg_no_params.sh \
+ sndrcv_omsnmpv1_udp.sh \
+ sndrcv_omsnmpv1_udp_dynsource.sh \
+ sndrcv_omsnmpv1_udp_invalidoid.sh \
+ snmptrapreceiver.py \
+ ommail_errmsg_no_params.sh \
+ mmdarwin_errmsg_no_params.sh \
+ mmdarwin_errmsg_no_sock.sh \
+ mmdarwin_errmsg_no_sock-vg.sh \
+ mmutf8fix_no_error.sh \
+ tcpflood_wrong_option_output.sh \
+ msleep_usage_output.sh \
+ mangle_qi_usage_output.sh \
+ minitcpsrv_usage_output.sh \
+ test_id_usage_output.sh \
+ mmanon_with_debug.sh \
+ mmanon_random_32_ipv4.sh \
+ mmanon_random_cons_32_ipv4.sh \
+ mmanon_recognize_ipv4.sh \
+ mmanon_zero_12_ipv4.sh \
+ mmanon_zero_33_ipv4.sh \
+ mmanon_zero_8_ipv4.sh \
+ mmanon_simple_12_ipv4.sh \
+ mmanon_simple_33_ipv4.sh \
+ mmanon_simple_8_ipv4.sh \
+ mmanon_simple_mallformed_ipv4.sh \
+ mmanon_random_128_ipv6.sh \
+ mmanon_zero_128_ipv6.sh \
+ mmanon_zero_96_ipv6.sh \
+ mmanon_random_cons_128_ipv6.sh \
+ mmanon_zero_50_ipv6.sh \
+ mmanon_recognize_ipv6.sh \
+ mmanon_zero_64_ipv6.sh \
+ mmanon_both_modes_compatible.sh \
+ mmanon_recognize_ipembedded.sh \
+ mmanon_ipv6_port.sh \
+ mmanon_random_cons_128_ipembedded.sh \
+ rscript_eq.sh \
+ rscript_eq_var.sh \
+ rscript_set_memleak-vg.sh \
+ rscript_set_unset_invalid_var.sh \
+ rscript_set_modify.sh \
+ stop-localvar.sh \
+ stop-msgvar.sh \
+ omfwd-tls-invalid-permitExpiredCerts.sh \
+ omfwd-keepalive.sh \
+ omfwd_fast_imuxsock.sh \
+ omfile_hup-vg.sh \
+ zstd.sh \
+ zstd-vg.sh \
+ gzipwr_hup-vg.sh \
+ omusrmsg-errmsg-no-params.sh \
+ omusrmsg-noabort.sh \
+ omusrmsg-noabort-vg.sh \
+ omfile-module-params.sh \
+ omfile-read-only-errmsg.sh \
+ omfile-null-filename.sh \
+ omfile-whitespace-filename.sh \
+ omfile-read-only.sh \
+ omfile-outchannel.sh \
+ omfile-outchannel-many.sh \
+ omfile-sizelimitcmd-many.sh \
+ omfile_both_files_set.sh \
+ omfile_hup.sh \
+ omrabbitmq_no_params.sh \
+ omrabbitmq_params_missing0.sh \
+ omrabbitmq_params_missing1.sh \
+ omrabbitmq_params_missing2.sh \
+ omrabbitmq_params_invalid0.sh \
+ omrabbitmq_params_invalid1.sh \
+ omrabbitmq_params_invalid2.sh \
+ omrabbitmq_params_invalid3.sh \
+ omrabbitmq_data_1server.sh \
+ omrabbitmq_data_1server-vg.sh \
+ omrabbitmq_data_2servers.sh \
+ omrabbitmq_error_server0.sh \
+ omrabbitmq_error_server1.sh \
+ omrabbitmq_error_server2.sh \
+ omrabbitmq_error_server3.sh \
+ omrabbitmq_json.sh \
+ omrabbitmq_raw.sh \
+ imhiredis-queue.sh \
+ imhiredis-queue-vg.sh \
+ imhiredis-queue-lpop.sh \
+ imhiredis-queue-lpop-vg.sh \
+ imhiredis-redis-restart.sh \
+ imhiredis-redis-restart-vg.sh \
+ imhiredis-redis-start-after.sh \
+ imhiredis-redis-start-after-vg.sh \
+ imhiredis-subscribe.sh \
+ imhiredis-subscribe-vg.sh \
+ imhiredis-stream.sh \
+ imhiredis-stream-vg.sh \
+ imhiredis-stream-from-beginning.sh \
+ imhiredis-stream-from-beginning-vg.sh \
+ imhiredis-stream-consumerGroup-ack.sh \
+ imhiredis-stream-consumerGroup-ack-vg.sh \
+ imhiredis-stream-consumerGroup-noack.sh \
+ imhiredis-stream-consumerGroup-noack-vg.sh \
+ imhiredis-stream-consumerGroup-reclaim.sh \
+ imhiredis-stream-consumerGroup-reclaim-vg.sh \
+ msgvar-concurrency.sh \
+ msgvar-concurrency-array.sh \
+ testsuites/msgvar-concurrency-array.rulebase \
+ msgvar-concurrency-array-event.tags.sh \
+ testsuites/msgvar-concurrency-array-event.tags.rulebase \
+ localvar-concurrency.sh \
+ exec_tpl-concurrency.sh \
+ prop-jsonmesg-vg.sh \
+ prop-all-json-concurrency.sh \
+ no-parser-errmsg.sh \
+ global_vars.sh \
+ no-parser-errmsg.sh \
+ no-parser-vg.sh \
+ prop-programname.sh \
+ prop-programname-with-slashes.sh \
+ rfc5424parser.sh \
+ rscript_privdropuser.sh \
+ rscript_privdropuserid.sh \
+ rscript_privdropgroup.sh \
+ rscript_privdropgroupid.sh \
+ privdrop_common.sh \
+ privdropuser.sh \
+ privdropuserid.sh \
+ privdropgroup.sh \
+ privdropgroupid.sh \
+ privdropabortonidfail.sh \
+ privdropabortonidfaillegacy.sh \
+ json-nonstring.sh \
+ json-onempty-at-end.sh \
+ template-json.sh \
+ template-pure-json.sh \
+ template-pos-from-to.sh \
+ template-pos-from-to-lowercase.sh \
+ template-pos-from-to-oversize.sh \
+ template-pos-from-to-oversize-lowercase.sh \
+ template-pos-from-to-missing-jsonvar.sh \
+ template-const-jsonf.sh \
+ template-topos-neg.sh \
+ fac_authpriv.sh \
+ fac_local0.sh \
+ fac_local0-vg.sh \
+ fac_local7.sh \
+ fac_mail.sh \
+ fac_news.sh \
+ fac_ftp.sh \
+ fac_ntp.sh \
+ fac_uucp.sh \
+ fac_invld1.sh \
+ fac_invld2.sh \
+ fac_invld3.sh \
+ fac_invld4_rfc5424.sh \
+ compresssp.sh \
+ compresssp-stringtpl.sh \
+ now_family_utc.sh \
+ now-utc-ymd.sh \
+ now-utc-casecmp.sh \
+ now-utc.sh \
+ now-unixtimestamp.sh \
+ faketime_common.sh \
+ imjournal-basic.sh \
+ imjournal-statefile.sh \
+ imjournal-statefile-vg.sh \
+ imjournal-basic-vg.sh \
+ omjournal-abort-template.sh \
+ omjournal-abort-no-template.sh \
+ omjournal-basic-template.sh \
+ omjournal-basic-no-template.sh \
+ timegenerated-ymd.sh \
+ timegenerated-uxtimestamp.sh \
+ timegenerated-uxtimestamp-invld.sh \
+ timegenerated-dateordinal.sh \
+ timegenerated-dateordinal-invld.sh \
+ timegenerated-utc.sh \
+ timegenerated-utc-legacy.sh \
+ timereported-utc.sh \
+ timereported-utc-legacy.sh \
+ timereported-utc-vg.sh \
+ mmrm1stspace-basic.sh \
+ mmnormalize_parsesuccess.sh \
+ mmnormalize_parsesuccess-vg.sh \
+ mmnormalize_rule_from_string.sh \
+ mmnormalize_rule_from_array.sh \
+ pmnull-basic.sh \
+ pmnull-withparams.sh \
+ omstdout-basic.sh \
+ testsuites/mmnormalize_processing_tests.rulebase \
+ mmnormalize_processing_test1.sh \
+ mmnormalize_processing_test2.sh \
+ mmnormalize_processing_test3.sh \
+ mmnormalize_processing_test4.sh \
+ pmnormalize-basic.sh \
+ pmnormalize-rule.sh \
+ pmnormalize-rule_and_rulebase.sh \
+ pmnormalize-neither_rule_rulebase.sh \
+ pmnormalize-invld-rulebase.sh \
+ pmnormalize-rule_invld-data.sh \
+ testsuites/pmnormalize_basic.rulebase \
+ pmnormalize-basic-vg.sh \
+ pmnormalize-rule-vg.sh\
+ pmnormalize-rule_and_rulebase-vg.sh \
+ pmnormalize-neither_rule_rulebase-vg.sh \
+ pmnormalize-invld-rulebase-vg.sh \
+ pmnormalize-rule_invld-data-vg.sh \
+ rawmsg-after-pri.sh \
+ rs_optimizer_pri.sh \
+ rscript_prifilt.sh \
+ rscript_optimizer1.sh \
+ rscript_ruleset_call.sh \
+ rscript_ruleset_call_indirect-basic.sh \
+ rscript_ruleset_call_indirect-var.sh \
+ rscript_ruleset_call_indirect-invld.sh \
+ cee_simple.sh \
+ cee_diskqueue.sh \
+ mmjsonparse-w-o-cookie.sh \
+ mmjsonparse-w-o-cookie-multi-spaces.sh \
+ mmjsonparse_simple.sh \
+ mmjsonparse-invalid-containerName.sh \
+ wtpShutdownAll-assertionFailure.sh \
+ imptcp-octet-framing-too-long-vg.sh \
+ imptcp-oversize-message-display.sh \
+ imptcp-msg-truncation-on-number.sh \
+ imptcp-msg-truncation-on-number2.sh \
+ imptcp-maxFrameSize-parameter.sh \
+ mmjsonparse_cim.sh \
+ mmjsonparse_cim2.sh \
+ mmjsonparse_localvar.sh \
+ mmdb.sh \
+ mmdb-space.sh \
+ mmdb.rb \
+ test.mmdb \
+ with_space.mmdb \
+ mmdb-vg.sh \
+ mmdb-container.sh \
+ mmdb-container-empty.sh \
+ mmdb-multilevel-vg.sh \
+ incltest.sh \
+ incltest_dir.sh \
+ incltest_dir_empty_wildcard.sh \
+ incltest_dir_wildcard.sh \
+ testsuites/es.yml \
+ clickhouse-dflt-tpl.sh \
+ clickhouse-retry-error.sh \
+ clickhouse-start.sh \
+ clickhouse-stop.sh \
+ clickhouse-basic.sh \
+ clickhouse-load.sh \
+ clickhouse-bulk.sh \
+ clickhouse-bulk-load.sh \
+ clickhouse-limited-batch.sh \
+ clickhouse-select.sh \
+ clickhouse-wrong-quotation-marks.sh \
+ clickhouse-wrong-template-option.sh \
+ clickhouse-errorfile.sh \
+ clickhouse-wrong-insert-syntax.sh \
+ clickhouse-basic-vg.sh \
+ clickhouse-load-vg.sh \
+ clickhouse-bulk-vg.sh \
+ clickhouse-bulk-load-vg.sh \
+ es_response_get_msgnum.py \
+ elasticsearch-error-format-check.py \
+ es-duplicated-ruleset.sh \
+ es-duplicated-ruleset-vg.sh \
+ es-basic-es6.0.sh \
+ es-basic-es7.14.sh \
+ es-basic.sh \
+ es-basic-vgthread.sh \
+ es-basic-server.sh \
+ es-execOnlyWhenPreviousSuspended.sh \
+ es-basic-ha.sh \
+ es-basic-bulk.sh \
+ es-basic-errfile-empty.sh \
+ es-basic-errfile-popul.sh \
+ es-bulk-errfile-empty.sh \
+ es-bulk-errfile-popul.sh \
+ es-bulk-errfile-popul-def-format.sh \
+ es-bulk-errfile-popul-erronly.sh \
+ es-bulk-errfile-popul-erronly-interleaved.sh \
+ es-bulk-errfile-popul-def-interleaved.sh \
+ es-searchType-empty.sh \
+ diskqueue-multithread-es.sh \
+ es-basic-vg.sh \
+ es-basic-bulk-vg.sh \
+ es-basic-ha-vg.sh \
+ es-maxbytes-bulk.sh \
+ es-bulk-retry.sh \
+ elasticsearch-stop.sh \
+ linkedlistqueue.sh \
+ da-mainmsg-q.sh \
+ diskqueue-fsync.sh \
+ msgdup.sh \
+ msgdup_props.sh \
+ empty-ruleset.sh \
+ ruleset-direct-queue.sh \
+ imtcp-listen-port-file-2.sh \
+ allowed-sender-tcp-ok.sh \
+ allowed-sender-tcp-fail.sh \
+ allowed-sender-tcp-hostname-ok.sh \
+ allowed-sender-tcp-hostname-fail.sh \
+ imtcp-octet-framing-too-long-vg.sh \
+ imtcp-discard-truncated-msg.sh \
+ imtcp-basic.sh \
+ imtcp-basic-hup.sh \
+ imtcp-maxFrameSize.sh \
+ imtcp-msg-truncation-on-number.sh \
+ imtcp-msg-truncation-on-number2.sh \
+ imtcp-NUL.sh \
+ imtcp-NUL-rawmsg.sh \
+ imtcp-tls-gtls-x509fingerprint-invld.sh \
+ imtcp-tls-gtls-x509fingerprint.sh \
+ imtcp-tls-gtls-x509name-invld.sh \
+ imtcp-tls-gtls-x509name.sh \
+ imtcp-tls-gtls-x509name-legacy.sh \
+ imtcp-drvr-in-input-basic.sh \
+ imtcp-multi-drvr-basic.sh \
+ imtcp-multi-drvr-basic-parallel.sh \
+ imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh \
+ imtcp-tls-basic.sh \
+ imtcp-tls-input-basic.sh \
+ imtcp-tls-input-2certs.sh \
+ imtcp-tls-basic-verifydepth.sh \
+ imtcp-tls-basic-vg.sh \
+ imtcp-tls-no-lstn-startup.sh \
+ imtcp_incomplete_frame_at_end.sh \
+ imtcp-multiport.sh \
+ imtcp-bigmessage-octetcounting.sh \
+ imtcp-bigmessage-octetstuffing.sh \
+ udp-msgreduc-orgmsg-vg.sh \
+ udp-msgreduc-vg.sh \
+ manytcp-too-few-tls-vg.sh \
+ imtcp-tls-ossl-basic.sh \
+ imtcp-tls-ossl-input-basic.sh \
+ imtcp-tls-ossl-input-2certs.sh \
+ imtcp-tls-ossl-basic-tlscommands.sh \
+ imtcp-tls-ossl-basic-verifydepth.sh \
+ imtcp-tls-ossl-invalid-verifydepth.sh \
+ sndrcv_tls_ossl_anon_ipv4.sh \
+ sndrcv_tls_ossl_anon_ipv6.sh \
+ sndrcv_tls_ossl_anon_rebind.sh \
+ sndrcv_tls_ossl_anon_ciphers.sh \
+ sndrcv_tls_ossl_certvalid.sh \
+ sndrcv_tls_ossl_certvalid_action_level.sh \
+ sndrcv_tls_ossl_certvalid_expired.sh \
+ sndrcv_tls_ossl_certvalid_tlscommand.sh \
+ sndrcv_tls_ossl_certvalid_ciphers.sh \
+ sndrcv_tls_ossl_certvalid_revoked.sh \
+ imtcp-tls-ossl-x509valid.sh \
+ imtcp-tls-ossl-x509name.sh \
+ imtcp-tls-ossl-x509fingerprint.sh \
+ imtcp-tls-ossl-basic-vg.sh \
+ imtcp-tls-ossl-basic-brokenhandshake-vg.sh \
+ imtcp-tls-ossl-error-ca.sh \
+ imtcp-tls-ossl-error-cert.sh \
+ imtcp-tls-ossl-error-key.sh \
+ imtcp-tls-ossl-error-key2.sh \
+ manytcp.sh \
+ manyptcp.sh \
+ imptcp-basic-hup.sh \
+ imptcp-NUL.sh \
+ imptcp-NUL-rawmsg.sh \
+ imptcp_framing_regex.sh \
+ testsuites/imptcp_framing_regex.testdata \
+ imptcp_framing_regex-oversize.sh \
+ testsuites/imptcp_framing_regex-oversize.testdata \
+ imptcp_large.sh \
+ imptcp-connection-msg-disabled.sh \
+ imptcp-connection-msg-received.sh \
+ imptcp-discard-truncated-msg.sh \
+ imptcp_addtlframedelim.sh \
+ imptcp_conndrop-vg.sh \
+ imptcp_conndrop.sh \
+ imptcp_multi_line.sh \
+ testsuites/imptcp_multi_line.testdata \
+ imptcp_no_octet_counted.sh \
+ imtcp_addtlframedelim_on_input.sh \
+ testsuites/no_octet_counted.testdata \
+ imtcp_no_octet_counted.sh \
+ testsuites/spframingfix.testdata \
+ imtcp_spframingfix.sh \
+ imtcp-connection-msg-recieved.sh \
+ imptcp_spframingfix.sh \
+ msg-deadlock-headerless-noappname.sh \
+ imtcp_conndrop.sh \
+ imtcp_conndrop_tls.sh \
+ imtcp_conndrop_tls-vg.sh \
+ imtcp_addtlframedelim.sh \
+ tcp-msgreduc-vg.sh \
+ inputname-imtcp.sh \
+ omod-if-array.sh \
+ omod-if-array-udp.sh \
+ discard.sh \
+ failover-no-rptd.sh \
+ failover-no-rptd-vg.sh \
+ failover-no-basic.sh \
+ failover-no-basic-vg.sh \
+ failover-rptd.sh \
+ failover-rptd-vg.sh \
+ failover-basic.sh \
+ failover-basic-vg.sh \
+ failover-async.sh \
+ failover-double.sh \
+ suspend-via-file.sh \
+ suspend-omfwd-via-file.sh \
+ externalstate-failed-rcvr.sh \
+ discard-rptdmsg.sh \
+ discard-rptdmsg-vg.sh \
+ discard-allmark.sh \
+ discard-allmark-vg.sh \
+ diag.sh \
+ rcvr_fail_restore.sh \
+ queue-encryption-disk.sh \
+ queue-encryption-disk_keyfile.sh \
+ queue-encryption-disk_keyfile-vg.sh \
+ queue-encryption-disk_keyprog.sh \
+ queue-encryption-da.sh \
+ da-queue-persist.sh \
+ daqueue-dirty-shutdown.sh \
+ daqueue-invld-qi.sh \
+ daqueue-persist.sh \
+ daqueue-persist-drvr.sh \
+ queue-persist.sh \
+ queue-persist-drvr.sh \
+ threadingmq.sh \
+ threadingmqaq.sh \
+ sndrcv_drvr.sh \
+ sndrcv_drvr_noexit.sh \
+ sndrcv_failover.sh \
+ sndrcv.sh \
+ omrelp_errmsg_no_connect.sh \
+ imrelp-basic.sh \
+ imrelp-basic-hup.sh \
+ imrelp-basic-vg.sh \
+ imrelp-basic-oldstyle.sh \
+ imrelp-manyconn.sh \
+ imrelp-manyconn-vg.sh \
+ imrelp-maxDataSize-error.sh \
+ imrelp-long-msg.sh \
+ imrelp-oversizeMode-truncate.sh \
+ imrelp-oversizeMode-accept.sh \
+ imrelp-invld-tlslib.sh \
+ imrelp-bigmessage.sh \
+ imrelp-sessionbreak-vg.sh \
+ omrelp-invld-tlslib.sh \
+ glbl-oversizeMsg-log.sh \
+ glbl-oversizeMsg-truncate.sh \
+ glbl-oversizeMsg-split.sh \
+ sndrcv_relp.sh \
+ sndrcv_relp_rebind.sh \
+ sndrcv_relp_tls_prio.sh \
+ sndrcv_relp_tls_chainedcert.sh \
+ sndrcv_relp_tls.sh \
+ sndrcv_relp_tls_certvalid.sh \
+ sndrcv_relp-vg-rcvr.sh \
+ sndrcv_relp-vg-sender.sh \
+ relp_tls_certificate_not_found.sh \
+ omrelp_wrong_authmode.sh \
+ imrelp-tls.sh \
+ imrelp-tls-cfgcmd.sh \
+ imrelp-tls-chainedcert.sh \
+ imrelp-tls-mixed-chainedcert.sh \
+ imrelp-tls-mixed-chainedcert2.sh \
+ sndrcv_relp_tls-cfgcmd.sh \
+ sndrcv_relp_dflt_pt.sh \
+ sndrcv_udp.sh \
+ imudp_thread_hang.sh \
+ sndrcv_udp_nonstdpt.sh \
+ sndrcv_udp_nonstdpt_v6.sh \
+ omudpspoof_errmsg_no_params.sh \
+ sndrcv_omudpspoof.sh \
+ sndrcv_omudpspoof-bigmsg.sh \
+ sndrcv_omudpspoof_nonstdpt.sh \
+ sndrcv_gzip.sh \
+ imdtls-basic.sh \
+ imdtls-basic-tlscommands.sh \
+ imdtls-basic-timeout \
+ imdtls-error-cert.sh \
+ imdtls-sessionbreak.sh \
+ imdtls-basic-vg.sh \
+ imdtls-sessionbreak-vg.sh \
+ sndrcv_dtls_certvalid.sh \
+ sndrcv_dtls_anon_ciphers.sh \
+ sndrcv_dtls_certvalid_ciphers.sh \
+ sndrcv_dtls_certvalid_permitted.sh \
+ sndrcv_dtls_certvalid_missing.sh \
+ sndrcv_dtls_anon_ciphers.sh \
+ sndrcv_dtls_certvalid-vg.sh \
+ action-tx-single-processing.sh \
+ omfwd-errfile-maxsize.sh \
+ omfwd-errfile-maxsize-filled.sh \
+ action-tx-errfile-maxsize.sh \
+ action-tx-errfile.sh \
+ testsuites/action-tx-errfile.result \
+ pipeaction.sh \
+ improg-simul.sh \
+ improg-multiline-test.py \
+ improg_errmsg_no_params.sh \
+ improg_errmsg_no_params-vg.sh \
+ improg_prog_simple.sh \
+ improg_prog_confirm.sh \
+ improg_prog_confirm_killonclose.sh \
+ improg_prog_killonclose.sh \
+ improg_prog_simple-vg.sh \
+ improg_simple_multi.sh \
+ imhttp-post-payload.sh \
+ imhttp-post-payload-vg.sh \
+ imhttp-post-payload-basic-auth.sh \
+ imhttp-post-payload-basic-auth-vg.sh \
+ imhttp-post-payload-query-params.sh \
+ imhttp-post-payload-query-params-vg.sh \
+ imhttp-post-payload-large.sh \
+ imhttp-post-payload-large-vg.sh \
+ testsuites/imhttp-large-data.txt \
+ imhttp-post-payload-multi.sh \
+ imhttp-post-payload-multi-vg.sh \
+ imhttp-getrequest-file.sh \
+ imhttp-getrequest-file-vg.sh \
+ imhttp-post-payload-multi-lf.sh \
+ imhttp-post-payload-multi-lf-vg.sh \
+ imhttp-post-payload-compress.sh \
+ imhttp-post-payload-compress-vg.sh \
+ testsuites/docroot/file.txt \
+ testsuites/htpasswd \
+ omhttp-auth.sh \
+ omhttp-basic.sh \
+ omhttp-batch-fail-with-400.sh \
+ omhttp-batch-jsonarray-compress.sh \
+ omhttp-batch-jsonarray-retry.sh \
+ omhttp-batch-jsonarray.sh \
+ omhttp-batch-kafkarest-retry.sh \
+ omhttp-batch-kafkarest.sh \
+ omhttp-batch-lokirest-retry.sh \
+ omhttp-batch-lokirest.sh \
+ omhttp-batch-lokirest-vg.sh \
+ omhttp-batch-newline.sh \
+ omhttp-retry.sh \
+ omhttp-httpheaderkey.sh \
+ omhttp-multiplehttpheaders.sh \
+ omhttp-dynrestpath.sh \
+ omhttp-batch-dynrestpath.sh \
+ omhttp-auth-vg.sh \
+ omhttp-basic-vg.sh \
+ omhttp-batch-jsonarray-compress-vg.sh \
+ omhttp-batch-jsonarray-retry-vg.sh \
+ omhttp-batch-jsonarray-vg.sh \
+ omhttp-batch-kafkarest-retry-vg.sh \
+ omhttp-batch-lokirest-retry-vg.sh \
+ omhttp-retry-vg.sh \
+ omhttp_server.py \
+ omprog-defaults.sh \
+ omprog-defaults-vg.sh \
+ omprog-output-capture.sh \
+ omprog-output-capture-mt.sh \
+ omprog-output-capture-vg.sh \
+ omprog-feedback.sh \
+ omprog-feedback-mt.sh \
+ omprog-feedback-vg.sh \
+ omprog-feedback-timeout.sh \
+ omprog-close-unresponsive.sh \
+ omprog-close-unresponsive-vg.sh \
+ omprog-close-unresponsive-noterm.sh \
+ omprog-restart-terminated.sh \
+ omprog-restart-terminated-vg.sh \
+ omprog-restart-terminated-outfile.sh \
+ omprog-single-instance.sh \
+ omprog-single-instance-vg.sh \
+ omprog-single-instance-outfile.sh \
+ omprog-if-error.sh \
+ omprog-transactions.sh \
+ omprog-transactions-vg.sh \
+ omprog-transactions-failed-messages.sh \
+ omprog-transactions-failed-commits.sh \
+ testsuites/omprog-defaults-bin.sh \
+ testsuites/omprog-output-capture-bin.sh \
+ testsuites/omprog-output-capture-mt-bin.py \
+ testsuites/omprog-feedback-bin.sh \
+ testsuites/omprog-feedback-mt-bin.sh \
+ testsuites/omprog-feedback-timeout-bin.sh \
+ testsuites/omprog-close-unresponsive-bin.sh \
+ testsuites/omprog-restart-terminated-bin.sh \
+ testsuites/omprog-single-instance-bin.sh \
+ testsuites/omprog-transactions-bin.sh \
+ pipe_noreader.sh \
+ uxsock_simple.sh \
+ asynwr_simple.sh \
+ asynwr_simple_2.sh \
+ asynwr_timeout.sh \
+ asynwr_timeout_2.sh \
+ asynwr_small.sh \
+ asynwr_tinybuf.sh \
+ wr_large_async.sh \
+ wr_large_sync.sh \
+ asynwr_deadlock.sh \
+ asynwr_deadlock_2.sh \
+ asynwr_deadlock2.sh \
+ asynwr_deadlock4.sh \
+ asynwr_dynfile_flushtxend-off.sh \
+ abort-uncleancfg-goodcfg.sh \
+ abort-uncleancfg-goodcfg-check.sh \
+ abort-uncleancfg-badcfg-check.sh \
+ abort-uncleancfg-badcfg-check_1.sh \
+ variable_leading_underscore.sh \
+ gzipwr_hup_multi_file.sh \
+ gzipwr_hup_single_file.sh \
+ gzipwr_rscript.sh \
+ gzipwr_flushInterval.sh \
+ gzipwr_flushOnTXEnd.sh \
+ gzipwr_large.sh \
+ gzipwr_large_dynfile.sh \
+ gzipwr_hup.sh \
+ complex1.sh \
+ random.sh \
+ testsuites/imfile-old-state-file_imfile-state_.-rsyslog.input \
+ imfile-readmode0-vg.sh \
+ imfile-readmode2.sh \
+ imfile-readmode2-polling.sh \
+ imfile-readmode2-vg.sh \
+ imfile-readmode2-with-persists-data-during-stop.sh \
+ imfile-readmode2-with-persists.sh \
+ imfile-endregex-save-lf.sh \
+ imfile-endregex-save-lf-persist.sh \
+ imfile-endregex.sh \
+ imfile-endregex-vg.sh \
+ imfile-basic.sh \
+ imfile-basic-legacy.sh \
+ imfile-basic-2GB-file.sh \
+ imfile-truncate-2GB-file.sh \
+ imfile-discard-truncated-line.sh \
+ imfile-truncate-line.sh \
+ imfile-file-not-found-error.sh \
+ imfile-fileNotFoundError-parameter.sh \
+ imfile-error-not-repeated.sh \
+ imfile-basic-vg.sh \
+ imfile-basic-vgthread.sh \
+ imfile-endregex-timeout-none-polling.sh \
+ imfile-endregex-timeout-polling.sh \
+ imfile-endregex-timeout.sh \
+ imfile-endregex-timeout-none.sh \
+ imfile-endregex-timeout-with-shutdown.sh \
+ imfile-endregex-timeout-with-shutdown-polling.sh \
+ imfile-escapelf.replacement.sh \
+ imfile-escapelf.replacement-empty.sh \
+ imfile-endmsg.regex.sh \
+ imfile-endmsg.regex-vg.sh \
+ imfile-endmsg.regex-with-example.sh \
+ imfile-endmsg.regex-with-example-vg.sh \
+ imfile-endmsg.regex.crio.rulebase \
+ imfile-endmsg.regex.json.rulebase \
+ imfile-statefile-no-file_id.sh \
+ imfile-statefile-no-file_id-TO-file_id.sh \
+ imfile-statefile-directory.sh \
+ imfile-statefile-delete.sh \
+ imfile-statefile-no-delete.sh \
+ imfile-persist-state-1.sh \
+ imfile-freshStartTail1.sh \
+ imfile-freshStartTail2.sh \
+ imfile-freshStartTail3.sh \
+ imfile-truncate.sh \
+ imfile-truncate-multiple.sh \
+ imfile-wildcards.sh \
+ imfile-wildcards-dirs.sh \
+ imfile-wildcards-dirs2.sh \
+ imfile-wildcards-dirs-multi.sh \
+ imfile-wildcards-dirs-multi2.sh \
+ imfile-wildcards-dirs-multi3.sh \
+ imfile-wildcards-dirs-multi4.sh \
+ imfile-wildcards-dirs-multi5.sh \
+ imfile-wildcards-dirs-multi5-polling.sh \
+ imfile-old-state-file.sh \
+ imfile-rename-while-stopped.sh \
+ imfile-rename.sh \
+ imfile-symlink.sh \
+ imfile-symlink-multi.sh \
+ imfile-symlink-ext-tmp-dir-tree.sh \
+ imfile-logrotate.sh \
+ imfile-logrotate-async.sh \
+ imfile-logrotate-copytruncate.sh \
+ imfile-logrotate-nocopytruncate.sh \
+ imfile-logrotate-multiple.sh \
+ imfile-growing-file-id.sh \
+ imfile-ignore-old-file-1.sh \
+ imfile-ignore-old-file-2.sh \
+ imfile-ignore-old-file-3.sh \
+ imfile-ignore-old-file-4.sh \
+ imfile-ignore-old-file-5.sh \
+ imfile-ignore-old-file-6.sh \
+ imfile-ignore-old-file-7.sh \
+ glbl-oversizeMsg-truncate-imfile.sh \
+ dynfile_invld_async.sh \
+ dynfile_invld_sync.sh \
+ dynfile_invalid2.sh \
+ rulesetmultiqueue.sh \
+ rulesetmultiqueue-v6.sh \
+ omruleset.sh \
+ omruleset-queue.sh \
+ badqi.sh \
+ bad_qi/dbq.qi \
+ execonlyonce.sh \
+ execonlywhenprevsuspended.sh \
+ execonlywhenprevsuspended2.sh \
+ execonlywhenprevsuspended3.sh \
+ execonlywhenprevsuspended4.sh \
+ execonlywhenprevsuspended_multiwrkr.sh \
+ execonlywhenprevsuspended-queue.sh \
+ execonlywhenprevsuspended-nonsusp.sh \
+ execonlywhenprevsuspended-nonsusp-queue.sh \
+ tabescape_dflt.sh \
+ tabescape_dflt-udp.sh \
+ tabescape_off.sh \
+ tabescape_off-udp.sh \
+ tabescape_on.sh \
+ dircreate_dflt.sh \
+ dircreate_off.sh \
+ imuxsock_legacy.sh \
+ imuxsock_logger_parserchain.sh \
+ imuxsock_logger.sh \
+ imuxsock_logger_ratelimit.sh \
+ imuxsock_logger_ruleset.sh \
+ imuxsock_logger_ruleset_ratelimit.sh \
+ imuxsock_logger_err.sh \
+ imuxsock_logger_root.sh \
+ imuxsock_logger_syssock.sh \
+ imuxsock_traillf.sh \
+ imuxsock_traillf_root.sh \
+ imuxsock_traillf_syssock.sh \
+ imuxsock_ccmiddle.sh \
+ imuxsock_ccmiddle_root.sh \
+ imklog_permitnonkernelfacility_root.sh \
+ imuxsock_ccmiddle_syssock.sh \
+ imuxsock_hostname.sh \
+ testsuites/mysql-truncate.sql \
+ testsuites/mysql-select-msg.sql \
+ libdbi-basic.sh \
+ libdbi-asyn.sh \
+ mysqld-start.sh \
+ mysqld-stop.sh \
+ mysql-basic.sh \
+ mysql-basic-cnf6.sh \
+ mysql-basic-vg.sh \
+ mysql-asyn.sh \
+ mysql-asyn-vg.sh \
+ mysql-actq-mt.sh \
+ mysql-actq-mt-withpause.sh \
+ mysql-actq-mt-withpause-vg.sh \
+ kafka-selftest.sh \
+ omkafka.sh \
+ omkafkadynakey.sh \
+ omkafka-vg.sh \
+ imkafka-hang-on-no-kafka.sh \
+ imkafka-hang-other-action-on-no-kafka.sh \
+ imkafka-backgrounded.sh \
+ imkafka-config-err-ruleset.sh \
+ imkafka-config-err-param.sh \
+ imkafka.sh \
+ imkafka-vg.sh \
+ imkafka_multi_single.sh \
+ imkafka_multi_group.sh \
+ sndrcv_kafka.sh \
+ sndrcv_kafka_multi_topics.sh \
+ testsuites/kafka-server.properties \
+ testsuites/kafka-server.dep_wrk1.properties \
+ testsuites/kafka-server.dep_wrk2.properties \
+ testsuites/kafka-server.dep_wrk3.properties \
+ testsuites/zoo.cfg \
+ testsuites/zoo.dep_wrk1.cfg \
+ testsuites/zoo.dep_wrk2.cfg \
+ testsuites/zoo.dep_wrk3.cfg \
+ omazureeventhubs-basic.sh \
+ omazureeventhubs-list.sh \
+ omazureeventhubs-stress.sh \
+ omazureeventhubs-interrupt.sh \
+ omazureeventhubs-basic-vg.sh \
+ omazureeventhubs-interrupt-vg.sh \
+ mmpstrucdata.sh \
+ mmpstrucdata-escaping.sh \
+ mmpstrucdata-case.sh \
+ mmpstrucdata-vg.sh \
+ mmpstrucdata-invalid-vg.sh \
+ libdbi-basic-vg.sh \
+ dynstats_ctr_reset.sh \
+ dynstats_reset_without_pstats_reset.sh \
+ dynstats_nometric.sh \
+ dynstats_overflow.sh \
+ dynstats_overflow-vg.sh \
+ dynstats_reset.sh \
+ dynstats_reset-vg.sh \
+ impstats-hup.sh \
+ dynstats.sh \
+ dynstats-vg.sh \
+ dynstats_prevent_premature_eviction.sh \
+ dynstats_prevent_premature_eviction-vg.sh \
+ testsuites/dynstats_empty_input \
+ testsuites/dynstats_input \
+ testsuites/dynstats_input_1 \
+ testsuites/dynstats_input_2 \
+ testsuites/dynstats_input_3 \
+ testsuites/dynstats_input_more_0 \
+ testsuites/dynstats_input_more_1 \
+ testsuites/dynstats_input_more_2 \
+ no-dynstats-json.sh \
+ no-dynstats.sh \
+ omfwd_impstats-udp.sh \
+ omfwd_impstats-tcp.sh \
+ perctile-simple.sh \
+ perctile-simple-vg.sh \
+ stats-json.sh \
+ stats-json-vg.sh \
+ stats-cee.sh \
+ stats-cee-vg.sh \
+ stats-json-es.sh \
+ dynstats-json.sh \
+ dynstats-json-vg.sh \
+ mmnormalize_variable.sh \
+ mmnormalize_tokenized.sh \
+ testsuites/mmnormalize_variable.rulebase \
+ testsuites/date_time_msg \
+ testsuites/mmnormalize_tokenized.rulebase \
+ testsuites/tokenized_input \
+ rscript_random.sh \
+ rscript_hash32.sh \
+ rscript_hash32-vg.sh \
+ rscript_hash64.sh \
+ rscript_hash64-vg.sh \
+ rscript_replace.sh \
+ rscript_replace_complex.sh \
+ testsuites/complex_replace_input \
+ rscript_unaffected_reset.sh \
+ rscript_wrap2.sh \
+ rscript_wrap3.sh \
+ testsuites/wrap3_input\
+ json_array_subscripting.sh \
+ testsuites/json_array_input \
+ testsuites/json_object_input \
+ testsuites/json_nonarray_input \
+ json_array_looping.sh \
+ json_object_looping.sh \
+ json_object_looping-vg.sh \
+ json_array_looping-vg.sh \
+ json_object_suicide_in_loop-vg.sh \
+ json_nonarray_looping.sh \
+ json_null.sh \
+ json_null-vg.sh \
+ json_null_array.sh \
+ json_null_array-vg.sh \
+ mmjsonparse_extra_data-vg.sh \
+ mmnormalize_regex.sh \
+ testsuites/mmnormalize_regex.rulebase \
+ testsuites/regex_input \
+ mmnormalize_regex_disabled.sh \
+ mmnormalize_regex_defaulted.sh \
+ stop_when_array_has_element.sh \
+ testsuites/stop_when_array_has_elem_input \
+ key_dereference_on_uninitialized_variable_space.sh \
+ rscript_re_extract_i.sh \
+ rscript_re_extract.sh \
+ rscript_re_match_i.sh \
+ rscript_re_match.sh \
+ rscript_re_match-dbl_quotes.sh \
+ lookup_table.sh \
+ lookup_table-hup-backgrounded.sh \
+ lookup_table_no_hup_reload.sh \
+ lookup_table_no_hup_reload-vg.sh \
+ lookup_table_rscript_reload.sh \
+ lookup_table_rscript_reload_without_stub.sh \
+ lookup_table_rscript_reload-vg.sh \
+ lookup_table_rscript_reload_without_stub-vg.sh \
+ rscript_trim-vg.sh \
+ testsuites/xlate.lkp_tbl \
+ testsuites/xlate_more.lkp_tbl \
+ unused_lookup_table-vg.sh \
+ lookup_table-vg.sh \
+ array_lookup_table.sh \
+ array_lookup_table-vg.sh \
+ array_lookup_table_misuse-vg.sh \
+ multiple_lookup_tables.sh \
+ multiple_lookup_tables-vg.sh \
+ testsuites/xlate_array.lkp_tbl \
+ testsuites/xlate_array_more.lkp_tbl \
+ testsuites/xlate_array_misuse.lkp_tbl \
+ testsuites/xlate_array_more_misuse.lkp_tbl \
+ sparse_array_lookup_table.sh \
+ sparse_array_lookup_table-vg.sh \
+ testsuites/xlate_sparse_array.lkp_tbl \
+ testsuites/xlate_sparse_array_more.lkp_tbl \
+ lookup_table_bad_configs.sh \
+ lookup_table_bad_configs-vg.sh \
+ testsuites/xlate_array_empty_table.lkp_tbl \
+ testsuites/xlate_array_no_index.lkp_tbl \
+ testsuites/xlate_array_no_table.lkp_tbl \
+ testsuites/xlate_array_no_value.lkp_tbl \
+ testsuites/xlate_empty_file.lkp_tbl \
+ testsuites/xlate_incorrect_type.lkp_tbl \
+ testsuites/xlate_incorrect_version.lkp_tbl \
+ testsuites/xlate_sparseArray_empty_table.lkp_tbl \
+ testsuites/xlate_sparseArray_no_index.lkp_tbl \
+ testsuites/xlate_sparseArray_no_table.lkp_tbl \
+ testsuites/xlate_sparseArray_no_value.lkp_tbl \
+ testsuites/xlate_string_empty_table.lkp_tbl \
+ testsuites/xlate_string_no_index.lkp_tbl \
+ testsuites/xlate_string_no_table.lkp_tbl \
+ testsuites/xlate_string_no_value.lkp_tbl \
+ testsuites/xlate_invalid_json.lkp_tbl \
+ testsuites/xlate_array_more_with_duplicates_and_nomatch.lkp_tbl \
+ testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl \
+ testsuites/xlate_sparse_array_more_with_duplicates_and_nomatch.lkp_tbl \
+ json_var_cmpr.sh \
+ imptcp_maxsessions.sh \
+ imptcp_nonProcessingPoller.sh \
+ imptcp_veryLargeOctateCountedMessages.sh \
+ known_issues.supp \
+ libmaxmindb.supp \
+ travis/trusty.supp \
+ linux_localtime_r.supp \
+ CI/centos6-9.supp \
+ CI/centos7.supp \
+ CI/gcov.supp \
+ CI/ubuntu20.04.supp \
+ json_var_case.sh \
+ cfg.sh \
+ empty-prop-comparison.sh \
+ sndrcv_tls_anon_rebind.sh \
+ sndrcv_tls_anon_hostname.sh \
+ sndrcv_tls_anon_ipv4.sh \
+ sndrcv_tls_anon_ipv6.sh \
+ sndrcv_tls_priorityString.sh \
+ sndrcv_tls_certvalid.sh \
+ sndrcv_tls_certvalid_action_level.sh \
+ sndrcv_tls_certvalid_expired.sh \
+ sndrcv_tls_certvalid_expired_defaultmode.sh \
+ sndrcv_tls_certvalid_revoked.sh \
+ sndrcv_tls_certless_clientonly.sh \
+ sndrcv_tls_gtls_servercert_gtls_clientanon.sh \
+ sndrcv_tls_gtls_servercert_gtls_clientanon_legacy.sh \
+ sndrcv_tls_gtls_serveranon_gtls_clientanon.sh \
+ sndrcv_tls_ossl_serveranon_ossl_clientanon.sh \
+ sndrcv_tls_ossl_servercert_ossl_clientanon.sh \
+ sndrcv_tls_ossl_servercert_gtls_clientanon.sh \
+ sndrcv_tls_ossl_serveranon_gtls_clientanon.sh \
+ sndrcv_tls_gtls_servercert_ossl_clientanon.sh \
+ sndrcv_tls_gtls_serveranon_ossl_clientanon.sh \
+ sndrcv_tls_client_missing_cert.sh \
+ sndrcv_ossl_cert_chain.sh \
+ omtcl.sh \
+ omtcl.tcl \
+ pmsnare-default.sh \
+ pmsnare-default-udp.sh \
+ pmsnare-ccoff.sh \
+ pmsnare-ccoff-udp.sh \
+ pmsnare-ccdefault.sh \
+ pmsnare-ccdefault-udp.sh \
+ pmsnare-cccstyle.sh \
+ pmsnare-cccstyle-udp.sh \
+ pmsnare-ccbackslash.sh \
+ pmsnare-ccbackslash-udp.sh \
+ pmsnare-modoverride.sh \
+ pmsnare-modoverride-udp.sh \
+ pmlastmsg.sh \
+ pmlastmsg-udp.sh \
+ pgsql-basic.sh \
+ testsuites/pgsql-basic.sql \
+ testsuites/pgsql-select-msg.sql \
+ testsuites/pgsql-select-syslogtag.sql \
+ pgsql-basic-cnf6.sh \
+ pgsql-basic-threads-cnf6.sh \
+ pgsql-template.sh \
+ pgsql-template-cnf6.sh \
+ pgsql-actq-mt-withpause.sh \
+ pgsql-template-threads-cnf6.sh \
+ pgsql-basic-vg.sh \
+ pgsql-template-vg.sh \
+ pgsql-basic-cnf6-vg.sh \
+ pgsql-template-cnf6-vg.sh \
+ pgsql-actq-mt-withpause-vg.sh \
+ ../devtools/prep-mysql-db.sh \
+ ../devtools/prepare_clickhouse.sh \
+ mmkubernetes-basic.sh \
+ mmkubernetes-basic-vg.sh \
+ mmkubernetes_test_server.py \
+ mmkubernetes-basic.out.json \
+ mmkubernetes-cache-expire.sh \
+ mmkubernetes-cache-expire-vg.sh \
+ mmkubernetes-cache-expire.out.expected \
+ mmkubernetes.supp \
+ es-writeoperation.sh \
+ imdocker-basic.sh \
+ imdocker-basic-vg.sh \
+ imdocker-long-logline.sh \
+ imdocker-long-logline-vg.sh \
+ imdocker-new-logs-from-start.sh \
+ imdocker-new-logs-from-start-vg.sh \
+ imdocker-multi-line.sh \
+ imdocker-multi-line-vg.sh \
+ testsuites/incltest.d/include.conf \
+ testsuites/abort-uncleancfg-goodcfg.conf \
+ testsuites/include-std-omfile-action.conf \
+ testsuites/invalid.conf \
+ testsuites/valid.conf \
+ testsuites/variable_leading_underscore.conf \
+ omamqp1-common.sh \
+ omamqp1-basic.sh \
+ omamqp1-basic-vg.sh
+
+ourtail_SOURCES = ourtail.c
+msleep_SOURCES = msleep.c
+omrelp_dflt_port_SOURCES = omrelp_dflt_port.c
+mangle_qi_SOURCES = mangle_qi.c
+chkseq_SOURCES = chkseq.c
+check_relpEngineVersion = check_relpEngineVersion.c
+have_relpSrvSetOversizeMode = have_relpSrvSetOversizeMode.c
+have_relpEngineSetTLSLibByName = have_relpEngineSetTLSLibByName.c
+have_relpSrvSetTlsConfigCmd = have_relpSrvSetTlsConfigCmd.c
+test_id_SOURCES = test_id.c
+uxsockrcvr_SOURCES = uxsockrcvr.c
+uxsockrcvr_LDADD = $(SOL_LIBS)
+tcpflood_SOURCES = tcpflood.c
+tcpflood_CFLAGS = $(PTHREADS_CFLAGS) $(RELP_CFLAGS) $(am__append_127) \
+ $(am__append_130)
+tcpflood_CPPFLAGS = $(PTHREADS_CFLAGS) $(RELP_CFLAGS) \
+ $(am__append_128) $(am__append_131)
+tcpflood_LDADD = $(SOL_LIBS) $(PTHREADS_LIBS) $(RELP_LIBS) \
+ $(am__append_129) $(am__append_132)
+minitcpsrv_SOURCES = minitcpsrvr.c
+minitcpsrv_LDADD = $(SOL_LIBS)
+syslog_caller_SOURCES = syslog_caller.c
+syslog_caller_CPPFLAGS = $(LIBLOGGING_STDLOG_CFLAGS)
+syslog_caller_LDADD = $(SOL_LIBS) $(LIBLOGGING_STDLOG_LIBS)
+journal_print_SOURCES = journal_print.c
+journal_print_CPPFLAGS = $(LIBSYSTEMD_JOURNAL_CFLAGS)
+journal_print_LDADD = $(LIBSYSTEMD_JOURNAL_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)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .sh .sh$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tests/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+set-envvars: $(top_builddir)/config.status $(srcdir)/set-envvars.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \
+ }
+
+uninstall-pkglibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
+ done
+
+clean-pkglibLTLIBRARIES:
+ -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
+ @list='$(pkglib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+liboverride_getaddrinfo.la: $(liboverride_getaddrinfo_la_OBJECTS) $(liboverride_getaddrinfo_la_DEPENDENCIES) $(EXTRA_liboverride_getaddrinfo_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(liboverride_getaddrinfo_la_LINK) $(am_liboverride_getaddrinfo_la_rpath) $(liboverride_getaddrinfo_la_OBJECTS) $(liboverride_getaddrinfo_la_LIBADD) $(LIBS)
+
+liboverride_gethostname.la: $(liboverride_gethostname_la_OBJECTS) $(liboverride_gethostname_la_DEPENDENCIES) $(EXTRA_liboverride_gethostname_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(liboverride_gethostname_la_LINK) $(am_liboverride_gethostname_la_rpath) $(liboverride_gethostname_la_OBJECTS) $(liboverride_gethostname_la_LIBADD) $(LIBS)
+
+liboverride_gethostname_nonfqdn.la: $(liboverride_gethostname_nonfqdn_la_OBJECTS) $(liboverride_gethostname_nonfqdn_la_DEPENDENCIES) $(EXTRA_liboverride_gethostname_nonfqdn_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(liboverride_gethostname_nonfqdn_la_LINK) $(am_liboverride_gethostname_nonfqdn_la_rpath) $(liboverride_gethostname_nonfqdn_la_OBJECTS) $(liboverride_gethostname_nonfqdn_la_LIBADD) $(LIBS)
+
+check_relpEngineVersion$(EXEEXT): $(check_relpEngineVersion_OBJECTS) $(check_relpEngineVersion_DEPENDENCIES) $(EXTRA_check_relpEngineVersion_DEPENDENCIES)
+ @rm -f check_relpEngineVersion$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(check_relpEngineVersion_OBJECTS) $(check_relpEngineVersion_LDADD) $(LIBS)
+
+chkseq$(EXEEXT): $(chkseq_OBJECTS) $(chkseq_DEPENDENCIES) $(EXTRA_chkseq_DEPENDENCIES)
+ @rm -f chkseq$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(chkseq_OBJECTS) $(chkseq_LDADD) $(LIBS)
+
+diagtalker$(EXEEXT): $(diagtalker_OBJECTS) $(diagtalker_DEPENDENCIES) $(EXTRA_diagtalker_DEPENDENCIES)
+ @rm -f diagtalker$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(diagtalker_OBJECTS) $(diagtalker_LDADD) $(LIBS)
+
+have_relpEngineSetTLSLibByName$(EXEEXT): $(have_relpEngineSetTLSLibByName_OBJECTS) $(have_relpEngineSetTLSLibByName_DEPENDENCIES) $(EXTRA_have_relpEngineSetTLSLibByName_DEPENDENCIES)
+ @rm -f have_relpEngineSetTLSLibByName$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(have_relpEngineSetTLSLibByName_OBJECTS) $(have_relpEngineSetTLSLibByName_LDADD) $(LIBS)
+
+have_relpSrvSetOversizeMode$(EXEEXT): $(have_relpSrvSetOversizeMode_OBJECTS) $(have_relpSrvSetOversizeMode_DEPENDENCIES) $(EXTRA_have_relpSrvSetOversizeMode_DEPENDENCIES)
+ @rm -f have_relpSrvSetOversizeMode$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(have_relpSrvSetOversizeMode_OBJECTS) $(have_relpSrvSetOversizeMode_LDADD) $(LIBS)
+
+have_relpSrvSetTlsConfigCmd$(EXEEXT): $(have_relpSrvSetTlsConfigCmd_OBJECTS) $(have_relpSrvSetTlsConfigCmd_DEPENDENCIES) $(EXTRA_have_relpSrvSetTlsConfigCmd_DEPENDENCIES)
+ @rm -f have_relpSrvSetTlsConfigCmd$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(have_relpSrvSetTlsConfigCmd_OBJECTS) $(have_relpSrvSetTlsConfigCmd_LDADD) $(LIBS)
+
+inputfilegen$(EXEEXT): $(inputfilegen_OBJECTS) $(inputfilegen_DEPENDENCIES) $(EXTRA_inputfilegen_DEPENDENCIES)
+ @rm -f inputfilegen$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(inputfilegen_OBJECTS) $(inputfilegen_LDADD) $(LIBS)
+
+journal_print$(EXEEXT): $(journal_print_OBJECTS) $(journal_print_DEPENDENCIES) $(EXTRA_journal_print_DEPENDENCIES)
+ @rm -f journal_print$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(journal_print_OBJECTS) $(journal_print_LDADD) $(LIBS)
+
+mangle_qi$(EXEEXT): $(mangle_qi_OBJECTS) $(mangle_qi_DEPENDENCIES) $(EXTRA_mangle_qi_DEPENDENCIES)
+ @rm -f mangle_qi$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(mangle_qi_OBJECTS) $(mangle_qi_LDADD) $(LIBS)
+
+miniamqpsrvr$(EXEEXT): $(miniamqpsrvr_OBJECTS) $(miniamqpsrvr_DEPENDENCIES) $(EXTRA_miniamqpsrvr_DEPENDENCIES)
+ @rm -f miniamqpsrvr$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(miniamqpsrvr_OBJECTS) $(miniamqpsrvr_LDADD) $(LIBS)
+
+minitcpsrv$(EXEEXT): $(minitcpsrv_OBJECTS) $(minitcpsrv_DEPENDENCIES) $(EXTRA_minitcpsrv_DEPENDENCIES)
+ @rm -f minitcpsrv$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(minitcpsrv_OBJECTS) $(minitcpsrv_LDADD) $(LIBS)
+
+msleep$(EXEEXT): $(msleep_OBJECTS) $(msleep_DEPENDENCIES) $(EXTRA_msleep_DEPENDENCIES)
+ @rm -f msleep$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(msleep_OBJECTS) $(msleep_LDADD) $(LIBS)
+
+omrelp_dflt_port$(EXEEXT): $(omrelp_dflt_port_OBJECTS) $(omrelp_dflt_port_DEPENDENCIES) $(EXTRA_omrelp_dflt_port_DEPENDENCIES)
+ @rm -f omrelp_dflt_port$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(omrelp_dflt_port_OBJECTS) $(omrelp_dflt_port_LDADD) $(LIBS)
+
+ourtail$(EXEEXT): $(ourtail_OBJECTS) $(ourtail_DEPENDENCIES) $(EXTRA_ourtail_DEPENDENCIES)
+ @rm -f ourtail$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(ourtail_OBJECTS) $(ourtail_LDADD) $(LIBS)
+
+randomgen$(EXEEXT): $(randomgen_OBJECTS) $(randomgen_DEPENDENCIES) $(EXTRA_randomgen_DEPENDENCIES)
+ @rm -f randomgen$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(randomgen_OBJECTS) $(randomgen_LDADD) $(LIBS)
+
+syslog_caller$(EXEEXT): $(syslog_caller_OBJECTS) $(syslog_caller_DEPENDENCIES) $(EXTRA_syslog_caller_DEPENDENCIES)
+ @rm -f syslog_caller$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(syslog_caller_OBJECTS) $(syslog_caller_LDADD) $(LIBS)
+
+tcpflood$(EXEEXT): $(tcpflood_OBJECTS) $(tcpflood_DEPENDENCIES) $(EXTRA_tcpflood_DEPENDENCIES)
+ @rm -f tcpflood$(EXEEXT)
+ $(AM_V_CCLD)$(tcpflood_LINK) $(tcpflood_OBJECTS) $(tcpflood_LDADD) $(LIBS)
+
+test_id$(EXEEXT): $(test_id_OBJECTS) $(test_id_DEPENDENCIES) $(EXTRA_test_id_DEPENDENCIES)
+ @rm -f test_id$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_id_OBJECTS) $(test_id_LDADD) $(LIBS)
+
+uxsockrcvr$(EXEEXT): $(uxsockrcvr_OBJECTS) $(uxsockrcvr_DEPENDENCIES) $(EXTRA_uxsockrcvr_DEPENDENCIES)
+ @rm -f uxsockrcvr$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(uxsockrcvr_OBJECTS) $(uxsockrcvr_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_relpEngineVersion.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chkseq.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diagtalker.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/have_relpEngineSetTLSLibByName.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/have_relpSrvSetOversizeMode.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/have_relpSrvSetTlsConfigCmd.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inputfilegen.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/journal_print-journal_print.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liboverride_getaddrinfo_la-override_getaddrinfo.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liboverride_gethostname_la-override_gethostname.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mangle_qi.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miniamqpsrvr-miniamqpsrvr.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minitcpsrvr.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msleep.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omrelp_dflt_port.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ourtail.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/randomgen.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syslog_caller-syslog_caller.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcpflood-tcpflood.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_id.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uxsockrcvr.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+liboverride_getaddrinfo_la-override_getaddrinfo.lo: override_getaddrinfo.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liboverride_getaddrinfo_la_CFLAGS) $(CFLAGS) -MT liboverride_getaddrinfo_la-override_getaddrinfo.lo -MD -MP -MF $(DEPDIR)/liboverride_getaddrinfo_la-override_getaddrinfo.Tpo -c -o liboverride_getaddrinfo_la-override_getaddrinfo.lo `test -f 'override_getaddrinfo.c' || echo '$(srcdir)/'`override_getaddrinfo.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liboverride_getaddrinfo_la-override_getaddrinfo.Tpo $(DEPDIR)/liboverride_getaddrinfo_la-override_getaddrinfo.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='override_getaddrinfo.c' object='liboverride_getaddrinfo_la-override_getaddrinfo.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liboverride_getaddrinfo_la_CFLAGS) $(CFLAGS) -c -o liboverride_getaddrinfo_la-override_getaddrinfo.lo `test -f 'override_getaddrinfo.c' || echo '$(srcdir)/'`override_getaddrinfo.c
+
+liboverride_gethostname_la-override_gethostname.lo: override_gethostname.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liboverride_gethostname_la_CFLAGS) $(CFLAGS) -MT liboverride_gethostname_la-override_gethostname.lo -MD -MP -MF $(DEPDIR)/liboverride_gethostname_la-override_gethostname.Tpo -c -o liboverride_gethostname_la-override_gethostname.lo `test -f 'override_gethostname.c' || echo '$(srcdir)/'`override_gethostname.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liboverride_gethostname_la-override_gethostname.Tpo $(DEPDIR)/liboverride_gethostname_la-override_gethostname.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='override_gethostname.c' object='liboverride_gethostname_la-override_gethostname.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liboverride_gethostname_la_CFLAGS) $(CFLAGS) -c -o liboverride_gethostname_la-override_gethostname.lo `test -f 'override_gethostname.c' || echo '$(srcdir)/'`override_gethostname.c
+
+liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.lo: override_gethostname_nonfqdn.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liboverride_gethostname_nonfqdn_la_CFLAGS) $(CFLAGS) -MT liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.lo -MD -MP -MF $(DEPDIR)/liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.Tpo -c -o liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.lo `test -f 'override_gethostname_nonfqdn.c' || echo '$(srcdir)/'`override_gethostname_nonfqdn.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.Tpo $(DEPDIR)/liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='override_gethostname_nonfqdn.c' object='liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(liboverride_gethostname_nonfqdn_la_CFLAGS) $(CFLAGS) -c -o liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.lo `test -f 'override_gethostname_nonfqdn.c' || echo '$(srcdir)/'`override_gethostname_nonfqdn.c
+
+journal_print-journal_print.o: journal_print.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(journal_print_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT journal_print-journal_print.o -MD -MP -MF $(DEPDIR)/journal_print-journal_print.Tpo -c -o journal_print-journal_print.o `test -f 'journal_print.c' || echo '$(srcdir)/'`journal_print.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/journal_print-journal_print.Tpo $(DEPDIR)/journal_print-journal_print.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='journal_print.c' object='journal_print-journal_print.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(journal_print_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o journal_print-journal_print.o `test -f 'journal_print.c' || echo '$(srcdir)/'`journal_print.c
+
+journal_print-journal_print.obj: journal_print.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(journal_print_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT journal_print-journal_print.obj -MD -MP -MF $(DEPDIR)/journal_print-journal_print.Tpo -c -o journal_print-journal_print.obj `if test -f 'journal_print.c'; then $(CYGPATH_W) 'journal_print.c'; else $(CYGPATH_W) '$(srcdir)/journal_print.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/journal_print-journal_print.Tpo $(DEPDIR)/journal_print-journal_print.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='journal_print.c' object='journal_print-journal_print.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(journal_print_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o journal_print-journal_print.obj `if test -f 'journal_print.c'; then $(CYGPATH_W) 'journal_print.c'; else $(CYGPATH_W) '$(srcdir)/journal_print.c'; fi`
+
+miniamqpsrvr-miniamqpsrvr.o: miniamqpsrvr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(miniamqpsrvr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT miniamqpsrvr-miniamqpsrvr.o -MD -MP -MF $(DEPDIR)/miniamqpsrvr-miniamqpsrvr.Tpo -c -o miniamqpsrvr-miniamqpsrvr.o `test -f 'miniamqpsrvr.c' || echo '$(srcdir)/'`miniamqpsrvr.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/miniamqpsrvr-miniamqpsrvr.Tpo $(DEPDIR)/miniamqpsrvr-miniamqpsrvr.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='miniamqpsrvr.c' object='miniamqpsrvr-miniamqpsrvr.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(miniamqpsrvr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o miniamqpsrvr-miniamqpsrvr.o `test -f 'miniamqpsrvr.c' || echo '$(srcdir)/'`miniamqpsrvr.c
+
+miniamqpsrvr-miniamqpsrvr.obj: miniamqpsrvr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(miniamqpsrvr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT miniamqpsrvr-miniamqpsrvr.obj -MD -MP -MF $(DEPDIR)/miniamqpsrvr-miniamqpsrvr.Tpo -c -o miniamqpsrvr-miniamqpsrvr.obj `if test -f 'miniamqpsrvr.c'; then $(CYGPATH_W) 'miniamqpsrvr.c'; else $(CYGPATH_W) '$(srcdir)/miniamqpsrvr.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/miniamqpsrvr-miniamqpsrvr.Tpo $(DEPDIR)/miniamqpsrvr-miniamqpsrvr.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='miniamqpsrvr.c' object='miniamqpsrvr-miniamqpsrvr.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(miniamqpsrvr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o miniamqpsrvr-miniamqpsrvr.obj `if test -f 'miniamqpsrvr.c'; then $(CYGPATH_W) 'miniamqpsrvr.c'; else $(CYGPATH_W) '$(srcdir)/miniamqpsrvr.c'; fi`
+
+syslog_caller-syslog_caller.o: syslog_caller.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syslog_caller_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT syslog_caller-syslog_caller.o -MD -MP -MF $(DEPDIR)/syslog_caller-syslog_caller.Tpo -c -o syslog_caller-syslog_caller.o `test -f 'syslog_caller.c' || echo '$(srcdir)/'`syslog_caller.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/syslog_caller-syslog_caller.Tpo $(DEPDIR)/syslog_caller-syslog_caller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='syslog_caller.c' object='syslog_caller-syslog_caller.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syslog_caller_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o syslog_caller-syslog_caller.o `test -f 'syslog_caller.c' || echo '$(srcdir)/'`syslog_caller.c
+
+syslog_caller-syslog_caller.obj: syslog_caller.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syslog_caller_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT syslog_caller-syslog_caller.obj -MD -MP -MF $(DEPDIR)/syslog_caller-syslog_caller.Tpo -c -o syslog_caller-syslog_caller.obj `if test -f 'syslog_caller.c'; then $(CYGPATH_W) 'syslog_caller.c'; else $(CYGPATH_W) '$(srcdir)/syslog_caller.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/syslog_caller-syslog_caller.Tpo $(DEPDIR)/syslog_caller-syslog_caller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='syslog_caller.c' object='syslog_caller-syslog_caller.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(syslog_caller_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o syslog_caller-syslog_caller.obj `if test -f 'syslog_caller.c'; then $(CYGPATH_W) 'syslog_caller.c'; else $(CYGPATH_W) '$(srcdir)/syslog_caller.c'; fi`
+
+tcpflood-tcpflood.o: tcpflood.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tcpflood_CPPFLAGS) $(CPPFLAGS) $(tcpflood_CFLAGS) $(CFLAGS) -MT tcpflood-tcpflood.o -MD -MP -MF $(DEPDIR)/tcpflood-tcpflood.Tpo -c -o tcpflood-tcpflood.o `test -f 'tcpflood.c' || echo '$(srcdir)/'`tcpflood.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tcpflood-tcpflood.Tpo $(DEPDIR)/tcpflood-tcpflood.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tcpflood.c' object='tcpflood-tcpflood.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tcpflood_CPPFLAGS) $(CPPFLAGS) $(tcpflood_CFLAGS) $(CFLAGS) -c -o tcpflood-tcpflood.o `test -f 'tcpflood.c' || echo '$(srcdir)/'`tcpflood.c
+
+tcpflood-tcpflood.obj: tcpflood.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tcpflood_CPPFLAGS) $(CPPFLAGS) $(tcpflood_CFLAGS) $(CFLAGS) -MT tcpflood-tcpflood.obj -MD -MP -MF $(DEPDIR)/tcpflood-tcpflood.Tpo -c -o tcpflood-tcpflood.obj `if test -f 'tcpflood.c'; then $(CYGPATH_W) 'tcpflood.c'; else $(CYGPATH_W) '$(srcdir)/tcpflood.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tcpflood-tcpflood.Tpo $(DEPDIR)/tcpflood-tcpflood.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tcpflood.c' object='tcpflood-tcpflood.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tcpflood_CPPFLAGS) $(CPPFLAGS) $(tcpflood_CFLAGS) $(CFLAGS) -c -o tcpflood-tcpflood.obj `if test -f 'tcpflood.c'; then $(CYGPATH_W) 'tcpflood.c'; else $(CYGPATH_W) '$(srcdir)/tcpflood.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+.sh.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.sh$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(pkglibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-pkglibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/check_relpEngineVersion.Po
+ -rm -f ./$(DEPDIR)/chkseq.Po
+ -rm -f ./$(DEPDIR)/diagtalker.Po
+ -rm -f ./$(DEPDIR)/have_relpEngineSetTLSLibByName.Po
+ -rm -f ./$(DEPDIR)/have_relpSrvSetOversizeMode.Po
+ -rm -f ./$(DEPDIR)/have_relpSrvSetTlsConfigCmd.Po
+ -rm -f ./$(DEPDIR)/inputfilegen.Po
+ -rm -f ./$(DEPDIR)/journal_print-journal_print.Po
+ -rm -f ./$(DEPDIR)/liboverride_getaddrinfo_la-override_getaddrinfo.Plo
+ -rm -f ./$(DEPDIR)/liboverride_gethostname_la-override_gethostname.Plo
+ -rm -f ./$(DEPDIR)/liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.Plo
+ -rm -f ./$(DEPDIR)/mangle_qi.Po
+ -rm -f ./$(DEPDIR)/miniamqpsrvr-miniamqpsrvr.Po
+ -rm -f ./$(DEPDIR)/minitcpsrvr.Po
+ -rm -f ./$(DEPDIR)/msleep.Po
+ -rm -f ./$(DEPDIR)/omrelp_dflt_port.Po
+ -rm -f ./$(DEPDIR)/ourtail.Po
+ -rm -f ./$(DEPDIR)/randomgen.Po
+ -rm -f ./$(DEPDIR)/syslog_caller-syslog_caller.Po
+ -rm -f ./$(DEPDIR)/tcpflood-tcpflood.Po
+ -rm -f ./$(DEPDIR)/test_id.Po
+ -rm -f ./$(DEPDIR)/uxsockrcvr.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-local distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-pkglibLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/check_relpEngineVersion.Po
+ -rm -f ./$(DEPDIR)/chkseq.Po
+ -rm -f ./$(DEPDIR)/diagtalker.Po
+ -rm -f ./$(DEPDIR)/have_relpEngineSetTLSLibByName.Po
+ -rm -f ./$(DEPDIR)/have_relpSrvSetOversizeMode.Po
+ -rm -f ./$(DEPDIR)/have_relpSrvSetTlsConfigCmd.Po
+ -rm -f ./$(DEPDIR)/inputfilegen.Po
+ -rm -f ./$(DEPDIR)/journal_print-journal_print.Po
+ -rm -f ./$(DEPDIR)/liboverride_getaddrinfo_la-override_getaddrinfo.Plo
+ -rm -f ./$(DEPDIR)/liboverride_gethostname_la-override_gethostname.Plo
+ -rm -f ./$(DEPDIR)/liboverride_gethostname_nonfqdn_la-override_gethostname_nonfqdn.Plo
+ -rm -f ./$(DEPDIR)/mangle_qi.Po
+ -rm -f ./$(DEPDIR)/miniamqpsrvr-miniamqpsrvr.Po
+ -rm -f ./$(DEPDIR)/minitcpsrvr.Po
+ -rm -f ./$(DEPDIR)/msleep.Po
+ -rm -f ./$(DEPDIR)/omrelp_dflt_port.Po
+ -rm -f ./$(DEPDIR)/ourtail.Po
+ -rm -f ./$(DEPDIR)/randomgen.Po
+ -rm -f ./$(DEPDIR)/syslog_caller-syslog_caller.Po
+ -rm -f ./$(DEPDIR)/tcpflood-tcpflood.Po
+ -rm -f ./$(DEPDIR)/test_id.Po
+ -rm -f ./$(DEPDIR)/uxsockrcvr.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pkglibLTLIBRARIES
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-pkglibLTLIBRARIES cscopelist-am ctags ctags-am distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-local distclean-tags distdir dvi dvi-am html html-am \
+ info info-am install install-am install-data install-data-am \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am \
+ install-pkglibLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+ uninstall-am uninstall-pkglibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@es-basic-es7.14.log: es-basic-es6.0.log
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@es-basic.log: es-basic-es7.14.log
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@es-basic-bulk.log: es-basic.log
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@es-basic-server.log: es-basic-bulk.log
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@elasticsearch-stop.log: es-basic-bulk.log
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@es-basic-vg.log: es-basic-bulk.log
+# for next if block:
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@es-basic-server.log: es-basic-vg.log
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@elasticsearch-stop.log: es-basic-vg.log
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_HELGRIND_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@es-basic-vgthread.log: es-basic-vg.log
+# for next if block:
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_HELGRIND_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@es-basic-server.log: es-basic-vgthread.log
+@ENABLE_ELASTICSEARCH_TESTS_MINIMAL_TRUE@@ENABLE_HELGRIND_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@elasticsearch-stop.log: es-basic-vgthread.log
+
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@es-basic-server.log: es-basic-bulk.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@es-execOnlyWhenPreviousSuspended.log: es-basic-server.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@es-maxbytes-bulk.log: es-execOnlyWhenPreviousSuspended.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@es-basic-errfile-empty.log: es-maxbytes-bulk.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@es-basic-errfile-popul.log: es-basic-errfile-empty.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@es-bulk-errfile-empty.log: es-basic-errfile-popul.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@es-bulk-errfile-popul.log: es-bulk-errfile-empty.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@es-searchType-empty.log: es-bulk-errfile-popul.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@diskqueue-multithread-es.log: es-searchType-empty.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@es-writeoperation.log: diskqueue-multithread-es.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@elasticsearch-stop.log: es-writeoperation.log
+
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@es-basic-ha.log: es-writeoperation.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@es-bulk-retry.log: es-basic-ha.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMPSTATS_TRUE@@ENABLE_TESTBENCH_TRUE@elasticsearch-stop.log: es-bulk-retry.log
+
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMFILE_TRUE@@ENABLE_TESTBENCH_TRUE@es-bulk-errfile-popul-def-format.log: es-bulk-retry.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMFILE_TRUE@@ENABLE_TESTBENCH_TRUE@es-bulk-errfile-popul-erronly.log: es-bulk-errfile-popul-def-format.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMFILE_TRUE@@ENABLE_TESTBENCH_TRUE@es-bulk-errfile-popul-erronly-interleaved.log: es-bulk-errfile-popul-erronly.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMFILE_TRUE@@ENABLE_TESTBENCH_TRUE@es-bulk-errfile-popul-def-interleaved.log: es-bulk-errfile-popul-erronly-interleaved.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_IMFILE_TRUE@@ENABLE_TESTBENCH_TRUE@elasticsearch-stop.log: es-bulk-errfile-popul-def-interleaved.log
+
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@es-basic-bulk-vg.log: es-writeoperation.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@es-basic-bulk-vg.log: es-bulk-retry.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@es-basic-bulk-vg.log: es-bulk-errfile-popul-def-interleaved.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@es-basic-ha-vg.log: es-basic-bulk-vg.log
+@ENABLE_ELASTICSEARCH_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@elasticsearch-stop.log: es-basic-ha-vg.log
+
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-basic.log: clickhouse-start.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-dflt-tpl.log: clickhouse-basic.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-retry-error.log: clickhouse-dflt-tpl.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-load.log: clickhouse-retry-error.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-bulk.log: clickhouse-load.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-bulk-load.log: clickhouse-bulk.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-limited-batch.log: clickhouse-bulk-load.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-select.log: clickhouse-limited-batch.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-errorfile.log: clickhouse-select.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-wrong-quotation-marks.log: clickhouse-errorfile.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-wrong-template-option.log: clickhouse-wrong-quotation-marks.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-wrong-insert-syntax.log: clickhouse-wrong-template-option.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@clickhouse-stop.log: clickhouse-wrong-insert-syntax.log
+
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@clickhouse-basic-vg.log: clickhouse-wrong-insert-syntax.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@clickhouse-load-vg.log: clickhouse-basic-vg.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@clickhouse-bulk-vg.log: clickhouse-load-vg.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@clickhouse-bulk-load-vg.log: clickhouse-bulk-vg.log
+@ENABLE_CLICKHOUSE_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@clickhouse-stop.log: clickhouse-bulk-load-vg.log
+
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@pgsql-basic-cnf6.log: pgsql-basic.log
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@pgsql-basic-threads-cnf6.log: pgsql-basic-cnf6.log
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@pgsql-template.log: pgsql-basic-threads-cnf6.log
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@pgsql-template-cnf6.log: pgsql-template.log
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@pgsql-actq-mt-withpause.log: pgsql-template-cnf6.log
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@pgsql-template-threads-cnf6.log: pgsql-actq-mt-withpause.log
+
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@pgsql-basic-vg.log: pgsql-template-threads-cnf6.log
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@pgsql-template-vg.log: pgsql-basic-vg.log
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@pgsql-basic-cnf6-vg.log: pgsql-template-vg.log
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@pgsql-template-cnf6-vg.log: pgsql-basic-cnf6-vg.log
+@ENABLE_PGSQL_TESTS_TRUE@@ENABLE_PGSQL_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@pgsql-actq-mt-withpause-vg.log: pgsql-template-cnf6-vg.log
+
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@mysql-basic.log: mysqld-start.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@mysql-basic-cnf6.log: mysqld-start.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@mysql-asyn.log: mysqld-start.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@mysql-actq-mt.log: mysqld-start.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@mysql-actq-mt-withpause.log: mysqld-start.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@action-tx-single-processing.log: mysqld-start.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@action-tx-errfile.log: mysqld-start.log
+
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@mysqld-stop.log: mysql-basic.log \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mysql-basic-cnf6.log \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mysql-asyn.log \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mysql-actq-mt.log \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ mysql-actq-mt-withpause.log \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ action-tx-single-processing.log \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@ action-tx-errfile.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@mysql-basic-vg.log: mysqld-start.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@mysql-asyn-vg.log: mysqld-start.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@mysql-actq-mt-withpause-vg.log: mysqld-start.log
+
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@mysqld-stop.log: mysql-basic-vg.log \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mysql-asyn-vg.log \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@ mysql-actq-mt-withpause-vg.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_OMLIBDBI_TRUE@@ENABLE_TESTBENCH_TRUE@libdbi-basic.log: mysqld-start.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_OMLIBDBI_TRUE@@ENABLE_TESTBENCH_TRUE@libdbi-asyn.log: mysqld-start.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_OMLIBDBI_TRUE@@ENABLE_TESTBENCH_TRUE@mysqld-stop.log: libdbi-basic.log \
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_OMLIBDBI_TRUE@@ENABLE_TESTBENCH_TRUE@ libdbi-asyn.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_OMLIBDBI_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@libdbi-basic-vg.log: mysqld-start.log
+@ENABLE_MYSQL_TESTS_TRUE@@ENABLE_OMLIBDBI_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@mysqld-stop.log: libdbi-basic-vg.log
+# Tests below need to be stable first!
+# sndrcv_kafka_fail.sh \
+# sndrcv_kafka_failresume.sh \
+# needs properly to much mempory on arm devices!
+# sndrcv_kafka_multi.sh
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@omkafka.log: kafka-selftest.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@imkafka.log: omkafka.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@imkafka-backgrounded.log: imkafka.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@imkafka-config-err-ruleset.log: imkafka-backgrounded.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@imkafka-config-err-param.log: imkafka-config-err-ruleset.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@imkafka-hang-on-no-kafka.log: imkafka-config-err-param.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@imkafka-hang-other-action-on-no-kafka.log: imkafka-hang-on-no-kafka.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@imkafka_multi_single.log: imkafka-hang-other-action-on-no-kafka.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@sndrcv_kafka.log: imkafka_multi_single.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@imkafka_multi_group.log: sndrcv_kafka.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@sndrcv_kafka_multi_topics.log: imkafka_multi_group.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@omkafkadynakey.log: sndrcv_kafka_multi_topics.log
+
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@omkafka-vg.log: sndrcv_kafka_multi_topics.log
+@ENABLE_IMKAFKA_TRUE@@ENABLE_KAFKA_TESTS_TRUE@@ENABLE_OMKAFKA_TRUE@@ENABLE_TESTBENCH_TRUE@@HAVE_VALGRIND_TRUE@imkafka-vg.log: omkafka-vg.log
+
+distclean-local:
+ rm -rf .dep_cache .dep_wrk
+
+# rtinit tests disabled for the moment - also questionable if they
+# really provide value (after all, everything fails if rtinit fails...)
+#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) $(SOL_LIBS)
+#rt_init_LDFLAGS = -export-dynamic
+
+# same for basic rscript tests
+#rscript_SOURCES = rscript.c getline.c $(test_files)
+#rscript_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS)
+#rscript_LDADD = $(RSRT_LIBS) $(ZLIB_LIBS) $(PTHREADS_LIBS) $(SOL_LIBS)
+#rscript_LDFLAGS = -export-dynamic
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/NoExistFile.cfgtest b/tests/NoExistFile.cfgtest
new file mode 100644
index 0000000..39d008f
--- /dev/null
+++ b/tests/NoExistFile.cfgtest
@@ -0,0 +1,2 @@
+rsyslogd: CONFIG ERROR: could not interpret master config file '/This/does/not/exist'. [try https://www.rsyslog.com/e/2013 ]
+rsyslogd: EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file!
diff --git a/tests/README b/tests/README
new file mode 100644
index 0000000..63a15d4
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,102 @@
+This directory contains the rsyslog testbench. It is slowly
+evolving. New tests are always welcome. So far, most tests check
+out the functionality of a single module. More complex tests are
+welcome.
+
+For a simple sample, see rtinit.c, which does a simple
+init/deinit check of the runtime system.
+
+Test Naming
+===========
+
+Test that use valgrind shall end in "-vg.sh".
+Test that use valgrind's helgrind thread debugger shall end in "-vgthread.sh".
+
+Setting up Test Environments
+============================
+
+Setting up MariaDB/MySQL
+------------------------
+to create the necessary user:
+
+echo "create user 'rsyslog'@'localhost' identified by 'testbench';" | mysql -u root
+mysql -u root < ../plugins/ommysql/createDB.sql
+echo "grant all on Syslog.* to 'rsyslog'@'localhost';" | mysql -u root
+
+openSUSE
+--------
+To configure system properties like hostname and firewall, use the
+graphical "yast2" administration tool. Note the ssh-access by default
+is disable in the firewall!
+
+Before running tests
+====================
+make check - this will compile all of the C code used in the tests, as well as
+do any other preparations, and will start running all of the tests. Ctrl-C to
+stop running all of the tests.
+
+Running all tests
+=================
+make check
+
+Running named tests
+===================
+make testname.log
+
+For example, to run the imfile-basic.sh test, use
+
+ make imfile-basic.log
+
+Test output is in imfile-basic.log
+
+To re-run the test, first remove imfile-basic.log then make again
+
+Or an alternative option is to run
+
+ make check TESTS='imfile-basic.sh'
+
+* Using gdb to debug rsyslog during a test run
+
+Edit your test like this:
+
+ . $srcdir/diag.sh startup
+ if [ -n "${USE_GDB:-}" ] ; then
+ echo attach gdb here
+ sleep 54321 || :
+ fi
+
+Run your test in the background:
+
+ USE_GDB=1 make mytest.sh.log &
+
+Tail mytest.sh.log until you see 'attach gdb here'. The log should also
+tell you what is the rsyslogd pid.
+
+ gdb ../tools/rsyslogd $rsyslogd_pid
+
+Set breakpoints, whatever, then 'continue'
+
+In another window, do ps -ef|grep 54321, then kill that pid
+
+Core Dump Analysis
+==================
+The testbench contains some limited (yet useful) support for automatically
+analyzing core dumps. In order for this to work, obviously core files need
+to be generated. This often doesn't work as intended. If you hit this problem,
+check
+
+1. ulimit -c unlimited (or a reasonable limit)
+ Note that root may need to increase a system-wide limit, which is
+ usually recorded in /etc/security/limits.conf
+ You need:
+ * soft core unlimited
+
+2. cat /proc/sys/kernel/core_pattern"
+ On systemd systems (and some others), the pattern is changed to save
+ core files so that systemd can import them -- with the result that the
+ testbench doesn't see them any longer. We require classic format, which
+ can be set via
+ $ sudo bash -c "echo \"core\" > /proc/sys/kernel/core_pattern"
+
+Note that you probably want to do neither of these changes to a production
+system.
diff --git a/tests/abort-uncleancfg-badcfg-check.sh b/tests/abort-uncleancfg-badcfg-check.sh
new file mode 100755
index 0000000..aa09eef
--- /dev/null
+++ b/tests/abort-uncleancfg-badcfg-check.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 2015-01-29 by Tim Eifler
+# This file is part of the rsyslog project, released under ASL 2.0
+# The configuration test should fail because of the invalid config file.
+. ${srcdir:=.}/diag.sh init
+../tools/rsyslogd -C -N1 -f$srcdir/testsuites/abort-uncleancfg-badcfg.conf -M../runtime/.libs:../.libs
+if [ $? == 0 ]; then
+ echo "Error: config check should fail"
+ error_exit 1
+fi
+printf 'unclean config lead to exit, as expected - OK\n'
+exit_test
+
diff --git a/tests/abort-uncleancfg-badcfg-check_1.sh b/tests/abort-uncleancfg-badcfg-check_1.sh
new file mode 100755
index 0000000..986688b
--- /dev/null
+++ b/tests/abort-uncleancfg-badcfg-check_1.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# Copyright 2015-01-29 by Tim Eifler
+# This file is part of the rsyslog project, released under ASL 2.0
+# The configuration test should fail because of the invalid config file.
+echo ===============================================================================
+echo \[abort-uncleancfg-badcfg_1.sh\]: testing abort on unclean configuration
+echo "testing a bad Configuration verification run"
+. ${srcdir:=.}/diag.sh init
+../tools/rsyslogd -C -N1 -f$srcdir/testsuites/abort-uncleancfg-badcfg_1.conf -M../runtime/.libs:../.libs
+if [ $? == 0 ]; then
+ echo "Error: config check should fail"
+ exit 1
+fi
+exit_test
+
diff --git a/tests/abort-uncleancfg-goodcfg-check.sh b/tests/abort-uncleancfg-goodcfg-check.sh
new file mode 100755
index 0000000..cc576a8
--- /dev/null
+++ b/tests/abort-uncleancfg-goodcfg-check.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 2015-01-29 by Tim Eifler
+# This file is part of the rsyslog project, released under ASL 2.0
+# The configuration test should pass because of the good config file.
+. ${srcdir:=.}/diag.sh init
+echo "testing a good Configuration verification run"
+../tools/rsyslogd -C -N1 -f$srcdir/testsuites/abort-uncleancfg-goodcfg.conf -M../runtime/.libs:../.libs
+if [ $? -ne 0 ]; then
+ echo "Error: config check fail"
+ exit 1
+fi
+exit_test
+
diff --git a/tests/abort-uncleancfg-goodcfg.sh b/tests/abort-uncleancfg-goodcfg.sh
new file mode 100755
index 0000000..7dcc92b
--- /dev/null
+++ b/tests/abort-uncleancfg-goodcfg.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Copyright 2015-01-29 by Tim Eifler
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[abort-uncleancfg-goodcfg.sh\]: testing abort on unclean configuration
+echo "testing a good Configuration verification run"
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$AbortOnUncleanConfig on
+$MainMsgQueueTimeoutShutdown 10000
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+injectmsg 1 10
+shutdown_when_empty
+wait_shutdown
+
+if [ ! -e $RSYSLOG_OUT_LOG ]
+then
+ echo "error: expected file does not exist"
+ error_exit 1
+fi
+exit_test
diff --git a/tests/action-tx-errfile-maxsize.sh b/tests/action-tx-errfile-maxsize.sh
new file mode 100755
index 0000000..eaff6d7
--- /dev/null
+++ b/tests/action-tx-errfile-maxsize.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# part of the rsyslog project, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=50 # enough to generate big file
+export MAX_ERROR_SIZE=100
+
+generate_conf
+add_conf '
+$ModLoad ../plugins/ommysql/.libs/ommysql
+global(errormessagestostderr.maxnumber="5")
+
+template(type="string" name="tpl" string="insert into SystemEvents (Message, Facility) values (\"%msg%\", %$!facility%)" option.sql="on")
+
+if((not($msg contains "error")) and ($msg contains "msgnum:")) then {
+ set $.num = field($msg, 58, 2);
+ if $.num % 2 == 0 then {
+ set $!facility = $syslogfacility;
+ } else {
+ set $/cntr = 0;
+ }
+ action(type="ommysql" name="mysql_action_errfile_maxsize" server="127.0.0.1" template="tpl"
+ db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench" action.errorfile="'$RSYSLOG2_OUT_LOG'" action.errorfile.maxsize="'$MAX_ERROR_SIZE'")
+}
+'
+mysql_prep_for_test
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+mysql_get_data
+check_file_exists ${RSYSLOG2_OUT_LOG}
+file_size_check ${RSYSLOG2_OUT_LOG} ${MAX_ERROR_SIZE}
+exit_test
diff --git a/tests/action-tx-errfile.sh b/tests/action-tx-errfile.sh
new file mode 100755
index 0000000..fd492d3
--- /dev/null
+++ b/tests/action-tx-errfile.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# added by Rainer Gerhards 2018-01-05
+# part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50 # sufficient for our needs!
+export SEQ_CHECK_OPTIONS=-i2
+check_sql_data_ready() {
+ mysql_get_data
+ seq_check --check-only 0 $((NUMMESSAGES - 2))
+}
+export QUEUE_EMPTY_CHECK_FUNC=check_sql_data_ready
+
+generate_conf
+add_conf '
+$ModLoad ../plugins/ommysql/.libs/ommysql
+global(errormessagestostderr.maxnumber="5")
+
+template(type="string" name="tpl" string="insert into SystemEvents (Message, Facility) values (\"%msg%\", %$!facility%)" option.sql="on")
+
+if((not($msg contains "error")) and ($msg contains "msgnum:")) then {
+ set $.num = field($msg, 58, 2);
+ if $.num % 2 == 0 then {
+ set $!facility = $syslogfacility;
+ } else {
+ set $/cntr = 0;
+ }
+ action(type="ommysql" name="mysql_action" server="127.0.0.1" template="tpl"
+ db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench" action.errorfile="'$RSYSLOG2_OUT_LOG'")
+}
+'
+mysql_prep_for_test
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="$(cat ${srcdir}/testsuites/action-tx-errfile.result)"
+cmp_exact ${RSYSLOG2_OUT_LOG}
+mysql_get_data
+seq_check 0 $((NUMMESSAGES - 2)) -i2
+exit_test
diff --git a/tests/action-tx-single-processing.sh b/tests/action-tx-single-processing.sh
new file mode 100755
index 0000000..43c9f2e
--- /dev/null
+++ b/tests/action-tx-single-processing.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=2000
+export SEQ_CHECK_OPTIONS=-i2
+check_sql_data_ready() {
+ mysql_get_data
+ seq_check --check-only 0 $((NUMMESSAGES - 2))
+}
+export QUEUE_EMPTY_CHECK_FUNC=check_sql_data_ready
+generate_conf
+add_conf '
+module(load="../plugins/ommysql/.libs/ommysql")
+global(errormessagestostderr.maxnumber="50")
+
+template(type="string" name="tpl" string="insert into SystemEvents (Message, Facility) values (\"%msg%\", %$!facility%)" option.sql="on")
+template(type="string" name="tpl2" string="%$.num%|%$!facility%|insert into SystemEvents (Message, Facility) values (\"%msg%\", %$!facility%)\n" option.sql="on")
+
+if($msg contains "msgnum:") then {
+ set $.num = field($msg, 58, 2);
+ if $.num % 2 == 0 then {
+ set $!facility = $syslogfacility;
+ } else {
+ set $/cntr = 0;
+ }
+ action(type="ommysql" name="mysql_action" server="127.0.0.1" template="tpl"
+ db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench")
+}
+action(type="omfile" file="'$RSYSLOG2_OUT_LOG'")
+'
+mysql_prep_for_test
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+mysql_get_data
+seq_check 0 $((NUMMESSAGES - 2))
+exit_test
diff --git a/tests/allowed-sender-tcp-fail.sh b/tests/allowed-sender-tcp-fail.sh
new file mode 100755
index 0000000..81b053e
--- /dev/null
+++ b/tests/allowed-sender-tcp-fail.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# check that we are able to receive messages from allowed sender
+# added 2019-08-15 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5 # it's just important that we get any messages at all
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="rs")
+
+$AllowedSender TCP,128.66.0.0/16 # this IP range is reserved by RFC5737
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+ruleset(name="rs") {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_DYNNAME.must-not-be-created'")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -m$NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+content_check --regex "connection request from disallowed sender .* discarded"
+check_file_not_exists "$RSYSLOG_DYNNAME.must-not-be-created"
+exit_test
diff --git a/tests/allowed-sender-tcp-hostname-fail.sh b/tests/allowed-sender-tcp-hostname-fail.sh
new file mode 100755
index 0000000..01ec9d7
--- /dev/null
+++ b/tests/allowed-sender-tcp-hostname-fail.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# check that we are able to receive messages from allowed sender
+# added 2019-08-19 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# Note: we need to know if CI supports DNS resolution. For this, we try to access
+# our rsyslog echo service. If that works, DNS obviously works. On the contrary
+# if we cannot access it, DNS might still work. But we prefer to skip the test in
+# that case (on rsyslog CI it will always work).
+rsyslog_testbench_test_url_access http://testbench.rsyslog.com/testbench/echo-get.php
+export NUMMESSAGES=5 # it's just important that we get any messages at all
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="rs")
+
+$AllowedSender TCP,www.rsyslog.com
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+ruleset(name="rs") {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_DYNNAME.must-not-be-created'")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -m$NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+content_check --regex "connection request from disallowed sender .* discarded"
+check_file_not_exists "$RSYSLOG_DYNNAME.must-not-be-created"
+exit_test
diff --git a/tests/allowed-sender-tcp-hostname-ok.sh b/tests/allowed-sender-tcp-hostname-ok.sh
new file mode 100755
index 0000000..282800e
--- /dev/null
+++ b/tests/allowed-sender-tcp-hostname-ok.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# check that we are able to receive messages from allowed sender
+# added 2019-08-15 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+setvar_RS_HOSTNAME
+export NUMMESSAGES=5 # it's just important that we get any messages at all
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$AllowedSender TCP,*'$RS_HOSTNAME'*
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -m$NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/allowed-sender-tcp-ok.sh b/tests/allowed-sender-tcp-ok.sh
new file mode 100755
index 0000000..75322ee
--- /dev/null
+++ b/tests/allowed-sender-tcp-ok.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# check that we are able to receive messages from allowed sender
+# added 2019-08-15 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5 # it's just important that we get any messages at all
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$AllowedSender TCP,127.0.0.1/16,[::1]
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -m$NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/array_lookup_table-vg.sh b/tests/array_lookup_table-vg.sh
new file mode 100755
index 0000000..1f3ccf5
--- /dev/null
+++ b/tests/array_lookup_table-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# added 2015-10-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/array_lookup_table.sh
diff --git a/tests/array_lookup_table.sh b/tests/array_lookup_table.sh
new file mode 100755
index 0000000..b141c0d
--- /dev/null
+++ b/tests/array_lookup_table.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# test for array lookup-table and HUP based reloading of it
+# added 2015-10-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate_array.lkp_tbl")
+
+template(name="outfmt" type="string" string="%msg% %$.lkp%\n")
+
+set $.num = field($msg, 58, 2);
+
+set $.lkp = lookup("xlate", $.num);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+cp -f $srcdir/testsuites/xlate_array.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl
+startup
+injectmsg 0 3
+wait_queueempty
+content_check "msgnum:00000000: foo_old"
+content_check "msgnum:00000001: bar_old"
+assert_content_missing "baz"
+cp -f $srcdir/testsuites/xlate_array_more.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 3
+wait_queueempty
+content_check "msgnum:00000000: foo_new"
+content_check "msgnum:00000001: bar_new"
+content_check "msgnum:00000002: baz"
+cp -f $srcdir/testsuites/xlate_array_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 12
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "msgnum:00000000: quux"
+content_check "msgnum:00000001: quux"
+content_check "msgnum:00000002: foo_latest"
+content_check "msgnum:00000003: baz_latest"
+content_check "msgnum:00000004: foo_latest"
+content_check "msgnum:00000005: foo_latest"
+content_check "msgnum:00000006: baz_latest"
+content_check "msgnum:00000007: foo_latest"
+content_check "msgnum:00000008: baz_latest"
+content_check "msgnum:00000009: baz_latest"
+content_check "msgnum:00000010: quux"
+content_check "msgnum:00000011: quux"
+exit_test
diff --git a/tests/array_lookup_table_misuse-vg.sh b/tests/array_lookup_table_misuse-vg.sh
new file mode 100755
index 0000000..26ca1c2
--- /dev/null
+++ b/tests/array_lookup_table_misuse-vg.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# test cleanup for array lookup-table and HUP based reloading of it
+# added 2015-10-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate_array.lkp_tbl")
+
+template(name="outfmt" type="string" string="%msg% %$.lkp%\n")
+
+set $.num = field($msg, 58, 2);
+
+set $.lkp = lookup("xlate", $.num);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+cp -f $srcdir/testsuites/xlate_array_misuse.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl
+startup_vg
+injectmsg 0 3
+wait_queueempty
+assert_content_missing "foo"
+assert_content_missing "bar"
+assert_content_missing "baz"
+cp -f $srcdir/testsuites/xlate_array_more_misuse.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 3
+wait_queueempty
+assert_content_missing "foo"
+assert_content_missing "bar"
+assert_content_missing "baz"
+cp -f $srcdir/testsuites/xlate_array_more.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 3
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+content_check "msgnum:00000000: foo_new"
+content_check "msgnum:00000001: bar_new"
+content_check "msgnum:00000002: baz"
+exit_test
diff --git a/tests/arrayqueue.sh b/tests/arrayqueue.sh
new file mode 100755
index 0000000..16008cc
--- /dev/null
+++ b/tests/arrayqueue.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Test for fixedArray queue mode
+# added 2009-05-20 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=40000
+generate_conf
+add_conf '
+# set spool locations and switch queue to disk-only mode
+$MainMsgQueueType FixedArray
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/asynwr_deadlock.sh b/tests/asynwr_deadlock.sh
new file mode 100755
index 0000000..34e28c9
--- /dev/null
+++ b/tests/asynwr_deadlock.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# This is test case from practice, with the version we introduced it, it
+# caused a deadlock on shutdown. I have added it to the test suite to automatically
+# detect such things in the future.
+#
+# added 2010-03-17 by Rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+echo ================================================================================
+echo TEST: \[asynwr_deadlock.sh\]: a case known to have caused a deadlock in the past
+. ${srcdir:=.}/diag.sh init
+export CI_SHUTDOWN_QUEUE_EMPTY_CHECKS=20 # this test is notoriously slow...
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+$InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port
+$InputTCPServerRun 0
+
+$template outfmt,"%msg:F,58:2%\n"
+
+$OMFileFlushOnTXEnd on
+$OMFileFlushInterval 10
+$OMFileIOBufferSize 10k
+$OMFileAsyncWriting on
+:msg, contains, "msgnum:" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="log"
+startup
+# just send one message
+tcpflood -m1
+# sleep is important! need to make sure the instance is inactive
+sleep 1
+# now try shutdown. The actual test is if the process does hang here!
+echo "processing must continue soon"
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+seq_check 0 0
+exit_test
diff --git a/tests/asynwr_deadlock2.sh b/tests/asynwr_deadlock2.sh
new file mode 100755
index 0000000..f656721
--- /dev/null
+++ b/tests/asynwr_deadlock2.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+# This is test case from practice, with the version we introduced it, it
+# caused a deadlock during processing (when the a stream was purged from the
+# dynafile cache).
+# We added this as a standard test in the hopes that iw will help
+# detect such things in the future.
+#
+# The problem that originally caused this test to fail was:
+# We write to files asynchronously (with the async writer thread). There is
+# no signaling done when the file stream is closed. That can lead to the writer
+# process hanging in memory, that in turn leads to the main thread waiting on a
+# condition that never occurs (because it would need to be signalled by the
+# async writer). Even worse, in that case, the async writer was signalled invalid
+# in such a way that when it received a wakeup, it thought it shall not terminate,
+# but received a spurios wakeup due to timeout and no data to write. In that case
+# it (correctly) concluded that it would not need to timeout until a new buffer write
+# was done (in which case it would receive a wakeup). As such, it went into an eternal
+# wait. However, the invalid signaling did not take into account that it did not
+# signal the async writer to shut down. So the main thread went into a condition
+# wait - and thus we had a deadlock. That situation occurred only under very specific
+# circumstances. As far as the analysis goes, the following need to happen:
+# 1. buffers on that file are being flushed
+# 2. no new data arrives
+# 3. the inactivity timeout has not yet expired
+# 4. *then* (and only then) the stream is closed or destructed
+# In that, 1 to 4 are prerequisites for the deadlock which will happen in 4. However,
+# for it to happen, we also need the right "timing". There is a race between the
+# main thread and the async writer thread. The deadlock will only happen under
+# the "right" circumstances, which basically means it will not happen always.
+# In order to create this case as reliable as possible, I have used
+# the "$OMFileFlushOnTXEnd on" directive
+# inside my test case. It makes sure that #1 above happens. The test uses a dynafile
+# cache size of 4, and the load generator generates data for 5 different dynafiles.
+# So over time, we will hit a spot where 4 dynafiles are open and the 5th file name
+# is generated. As such, one file needs to be discarded. Thanks to FlushOnTXEnd, we
+# now likely have #2 in place and thanks to the load pattern generated, we most
+# probably have #3 in place. During the dynafile cache displacement of the oldest
+# entry, #4 is generated. At this point, we have the deadlock we are testing for.
+# Note that this deadlock does not necessarily lead to a total lockup of rsyslogd.
+# Parts of it continue to operate. But in our test setup, this means data is
+# received and placed into the main queue. Once it's high water mark is hit, data
+# is still being enqueued, but at a slow rate. So if one is patient enough, the load
+# generator will be able to finish. However, rsyslogd will never process the data
+# it received because it is locked in the deadlock caused by #4 above.
+# Note that "$OMFileFlushOnTXEnd on" is not causing this behavior. We just use it
+# to (quite) reliably cause the failure condition. The failure described above
+# (in version 4.6.1) was also present when the setting was set to "off", but its
+# occurrence was very much less probable - because the perquisites are then much
+# harder to hit. without it, the test may need to run for several hours before
+# we hit all failure conditions.
+#
+# added 2010-03-17 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export CI_SHUTDOWN_QUEUE_EMPTY_CHECKS=20 # this test is notoriously slow...
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+$InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port
+$InputTCPServerRun 0
+
+$template outfmt,"%msg:F,58:3%,%msg:F,58:4%,%msg:F,58:5%\n"
+$template dynfile,"'$RSYSLOG_DYNNAME'.%msg:F,58:2%.log" # use multiple dynafiles
+
+$OMFileFlushOnTXEnd on
+$OMFileFlushInterval 10
+$OMFileIOBufferSize 10k
+$OMFileAsyncWriting on
+$DynaFileCacheSize 4
+local0.* ?dynfile;outfmt
+'
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="log"
+startup
+# send 20000 messages, each close to 2K (non-randomized!), so that we can fill
+# the buffers and hopefully run into the "deadlock".
+tcpflood -m20000 -d1800 -P129 -i1 -f5
+shutdown_when_empty
+wait_shutdown
+cat $RSYSLOG_DYNNAME.*.log > $RSYSLOG_OUT_LOG
+seq_check 1 20000 -E
+rm -f $RSYSLOG_DYNNAME.*.log
+exit_test
diff --git a/tests/asynwr_deadlock4.sh b/tests/asynwr_deadlock4.sh
new file mode 100755
index 0000000..41dece3
--- /dev/null
+++ b/tests/asynwr_deadlock4.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# This is test case from practice, with the version we introduced it, it
+# caused a deadlock during processing.
+# We added this as a standard test in the hopes that iw will help
+# detect such things in the future.
+#
+# This is a test that is constructed similar to asynwr_deadlock2.sh, but
+# can produce problems in a simpler way.
+#
+# added 2010-03-18 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=20000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+$InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port
+$InputTCPServerRun 0
+
+$template outfmt,"%msg:F,58:3%,%msg:F,58:4%,%msg:F,58:5%\n"
+template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'")
+
+$OMFileFlushOnTXEnd on
+$OMFileFlushInterval 10
+$OMFileIOBufferSize 10k
+$OMFileAsyncWriting on
+$DynaFileCacheSize 4
+local0.* ?dynfile;outfmt
+'
+startup
+# send 20000 messages, each close to 2K (non-randomized!), so that we can fill
+# the buffers and hopefully run into the "deadlock".
+tcpflood -m20000 -d18 -P129 -f5
+shutdown_when_empty
+wait_shutdown
+export SEQ_CHECK_OPTIONS=-E
+seq_check
+exit_test
diff --git a/tests/asynwr_deadlock_2.sh b/tests/asynwr_deadlock_2.sh
new file mode 100755
index 0000000..6447706
--- /dev/null
+++ b/tests/asynwr_deadlock_2.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# This is test case from practice, with the version we introduced it, it
+# caused a deadlock on shutdown. I have added it to the test suite to automatically
+# detect such things in the future.
+# a case known to have caused a deadlock in the past
+#
+# added 2010-03-17 by Rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+
+$OMFileFlushOnTXEnd on
+$OMFileFlushInterval 10
+$OMFileIOBufferSize 4k
+$OMFileAsyncWriting on
+:msg, contains, "msgnum:" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood
+wait_file_lines # wait to become inactive - important bug trigger contidion
+# now try shutdown. The actual test is if the process does hang here!
+echo "processing must continue soon"
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/asynwr_dynfile_flushtxend-off.sh b/tests/asynwr_dynfile_flushtxend-off.sh
new file mode 100755
index 0000000..b734932
--- /dev/null
+++ b/tests/asynwr_dynfile_flushtxend-off.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# This tests async writing functionality under a set of additional
+# conditions (see config for details). This covers non-async cases as
+# well. This test was created while actually hunting a bug that was
+# very hard to reproduce but severe. While it had different trigger
+# conditions, the set of config parameters in this test helped to find
+# it quickly. As such the hope is the test will be useful in future again.
+#
+# NOTE WELL: The rsyslog shutdown condition is hard to get 100% right
+# as due to not flushing at transaction end we cannot rely on the output
+# file count as we usually do. However, we cannot avoid this as otherwise
+# we loose an important trigger condition.
+# added 2019-10-23 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export CI_SHUTDOWN_QUEUE_EMPTY_CHECKS=30 # this test is notoriously slow...
+export NUMMESSAGES=20000
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:3%,%msg:F,58:4%,%msg:F,58:5%\n")
+template(name="dynfile" type="string" string="'$RSYSLOG_DYNNAME'.%msg:F,58:2%.log") # use multiple dynafiles
+
+local0.* action(type="omfile" dynafile="dynfile" template="outfmt"
+ flushOnTXEnd="off" flushInterval="10" ioBufferSize="10k"
+ asyncWriting="on" dynaFileCacheSize="4")
+'
+# uncomment for debugging support:
+startup
+tcpflood -m$NUMMESSAGES -d1800 -P129 -f5
+shutdown_when_empty
+wait_shutdown
+cat $RSYSLOG_DYNNAME.*.log > $RSYSLOG_OUT_LOG
+export SEQ_CHECK_OPTIONS=-E
+seq_check
+exit_test
diff --git a/tests/asynwr_simple.sh b/tests/asynwr_simple.sh
new file mode 100755
index 0000000..9fdbc67
--- /dev/null
+++ b/tests/asynwr_simple.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# This is test driver for testing asynchronous file output.
+# This test intentionally uses legacy format.
+# added 2010-03-09 by Rgerhards, re-written 2019-08-15
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# send 35555 messages, make sure file size is not a multiple of
+# 10K, the buffer size!
+export NUMMESSAGES=355555
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'")
+$OMFileFlushOnTXEnd off
+$OMFileFlushInterval 2
+$OMFileIOBufferSize 10k
+$OMFileAsyncWriting on
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/asynwr_simple_2.sh b/tests/asynwr_simple_2.sh
new file mode 100755
index 0000000..7a7f9dd
--- /dev/null
+++ b/tests/asynwr_simple_2.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# This is test driver for testing asynchronous file output.
+# added 2010-03-09 by Rgerhards, re-written 2019-08-15
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# send 35555 messages, make sure file size is not a multiple of
+# 4K, the buffer size!
+export NUMMESSAGES=355555
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:"
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt"
+ asyncWriting="on" flushOnTXEnd="off" flushInterval="2" ioBufferSize="4k")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/asynwr_small.sh b/tests/asynwr_small.sh
new file mode 100755
index 0000000..5d45238
--- /dev/null
+++ b/tests/asynwr_small.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# This tests async writing with only a small set of data. That
+# shall result in data staying in buffers until shutdown, what
+# then will trigger some somewhat complex logic in the stream
+# writer (open, write, close all during the stream close
+# operation). It is vital that only few messages be sent.
+#
+# The main effort of this test is not (only) to see if we
+# receive the data, but rather to see if we get into an abort
+# condition.
+#
+# added 2010-03-09 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=2
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+$InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port
+$InputTCPServerRun 0
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+$OMFileFlushOnTXEnd off
+$OMFileFlushInterval 2
+$OMFileAsyncWriting on
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="log"
+startup
+tcpflood
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/asynwr_timeout.sh b/tests/asynwr_timeout.sh
new file mode 100755
index 0000000..5c990a2
--- /dev/null
+++ b/tests/asynwr_timeout.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# This test writes to the output buffers, let's the output
+# write timeout (and write data) and then continue. The conf file
+# has a 2 second timeout, so we wait 4 seconds to be on the save side.
+#
+# added 2010-03-09 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# send 35555 messages, make sure file size is not a multiple of
+# 10K, the buffer size!
+export NUMMESSAGES=15555
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'")
+$OMFileFlushOnTXEnd off
+$OMFileFlushInterval 2
+$OMFileIOBufferSize 10k
+$OMFileAsyncWriting on
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+tcpflood -m $NUMMESSAGES
+printf 'waiting for timeout to occur\n'
+sleep 15 # GOOD SLEEP - we wait for the timeout! long to take care of slow test machines...
+printf 'timeout should now have occurred - check file state\n'
+seq_check
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/asynwr_timeout_2.sh b/tests/asynwr_timeout_2.sh
new file mode 100755
index 0000000..0cbbd4d
--- /dev/null
+++ b/tests/asynwr_timeout_2.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# This test writes to the output buffers, let's the output
+# write timeout (and write data) and then continue. The conf file
+# has a 2 second timeout, so we wait 4 seconds to be on the save side.
+#
+# added 2010-03-09 by Rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo TEST: \[asynwr_timeout.sh\]: test async file writing timeout writes
+. ${srcdir:=.}/diag.sh init
+export CI_SHUTDOWN_QUEUE_EMPTY_CHECKS=20 # this test is notoriously slow...
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+$OMFileFlushOnTXEnd off
+$OMFileFlushInterval 2
+$OMFileIOBufferSize 4k
+$OMFileAsyncWriting on
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="log"
+startup
+# send 35555 messages, make sure file size is not a multiple of
+# 4K, the buffer size!
+tcpflood -m 35555
+sleep 4 # wait for output writer to write and empty buffer
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+seq_check 0 35554
+exit_test
diff --git a/tests/asynwr_tinybuf.sh b/tests/asynwr_tinybuf.sh
new file mode 100755
index 0000000..60da2fc
--- /dev/null
+++ b/tests/asynwr_tinybuf.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# This tests async writing with a very small output buffer (1 byte!),
+# so it stresses output buffer handling. This also means operations will
+# be somewhat slow, so we send only a small amounts of data.
+#
+# added 2010-03-09 by Rgerhards
+#
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo TEST: \[asynwr_tinybuf.sh\]: test async file writing with 1-byte buffer
+. ${srcdir:=.}/diag.sh init
+export CI_SHUTDOWN_QUEUE_EMPTY_CHECKS=20 # this test is notoriously slow...
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+$OMFileFlushOnTXEnd off
+$OMFileFlushInterval 2
+$OMFileIOBufferSize 1
+$OMFileAsyncWriting on
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="log"
+startup
+# send 1000 messages, fairly enough to trigger problems
+tcpflood -m1000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # shut down rsyslogd when done processing messages
+seq_check 0 999
+exit_test
diff --git a/tests/bad_qi/dbq.qi b/tests/bad_qi/dbq.qi
new file mode 100644
index 0000000..5f56e41
--- /dev/null
+++ b/tests/bad_qi/dbq.qi
@@ -0,0 +1,29 @@
+!OPB:1:queue:1:
++iQueueSize:2:2:84:
++iUngottenObjs:2:1:1:
++tVars.disk.sizeOnDisk:2:5:57906:
++tVars.disk.bytesRead:2:4:1010:
+>End
+.
+<Obj:1:strm:1:
++iCurrFNum:2:1:1:
++pszFName:1:3:dbq:
++iMaxFiles:2:8:10000000:
++bDeleteOnClose:2:1:0:
++sType:2:1:1:
++tOperationsMode:2:1:2:
++tOpenMode:2:3:384:
++iCurrOffs:2:5:57906:
+>End
+.
+<Obj:1:strm:1:
++iCurrFNum:2:1:1:
++pszFName:1:3:dbq:
++iMaxFiles:2:8:10000000:
++bDeleteOnClose:2:1:1:
++sType:2:1:1:
++tOperationsMode:2:1:1:
++tOpenMode:2:3:384:
++iCurrOffs:2:4:1010:
+>End
+.
diff --git a/tests/badqi.sh b/tests/badqi.sh
new file mode 100755
index 0000000..733c896
--- /dev/null
+++ b/tests/badqi.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# Test for a startup with a bad qi file. This tests simply tests
+# if the rsyslog engine survives (we had segfaults in this situation
+# in the past).
+# added 2009-10-21 by RGerhards
+# This file is part of the rsyslog project, released under GPLv3
+# uncomment for debugging support:
+echo ===============================================================================
+echo \[badqi.sh\]: test startup with invalid .qi file
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+# instruct to use bad .qi file
+$WorkDirectory bad_qi
+$ActionQueueType LinkedList
+$ActionQueueFileName dbq
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+# we just inject a handful of messages so that we have something to wait for...
+tcpflood -m20
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # wait for process to terminate
+seq_check 0 19
+exit_test
diff --git a/tests/cee_diskqueue.sh b/tests/cee_diskqueue.sh
new file mode 100755
index 0000000..172c429
--- /dev/null
+++ b/tests/cee_diskqueue.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# check if CEE properties are properly saved & restored to/from disk queue
+# added 2012-09-19 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test probably does not work on all flavors of Solaris"
+export NUMMESSAGES=5000
+generate_conf
+add_conf '
+global(workDirectory="'$RSYSLOG_DYNNAME.spool'")
+template(name="outfmt" type="string" string="%$!usr!msg:F,58:2%\n")
+
+set $!usr!msg = $msg;
+if $msg contains "msgnum" then
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt"
+ queue.type="disk" queue.filename="rsyslog-act1")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/cee_simple.sh b/tests/cee_simple.sh
new file mode 100755
index 0000000..b81e6d1
--- /dev/null
+++ b/tests/cee_simple.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# added 2012-09-19 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[cee_simple.sh\]: basic CEE property test
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!usr!msg:F,58:2%\n")
+set $!usr!msg = $msg;
+if $msg contains '
+add_conf "'msgnum' "
+add_conf 'then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/cfg.sh b/tests/cfg.sh
new file mode 100755
index 0000000..5e2f81b
--- /dev/null
+++ b/tests/cfg.sh
@@ -0,0 +1,140 @@
+#!/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 verification 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
+echo \[cfg.sh\]:
+rm -f tmp
+echo "local directory"
+#
+# check empty config file
+#
+../tools/rsyslogd -c4 -N1 -f/dev/null -M../runtime/.libs:../.libs 2>&1 |./ourtail |head -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 -c4 -N1 -M../runtime/.libs:../.libs -f/This/does/not/exist 2>&1 |./ourtail |head -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 -c4 -u2 -N1 -f$srcdir/cfg1.testin 2>&1 |./ourtail > 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 -c4 -u2 -N1 -f$srcdir/cfg2.testin 2>&1 |./ourtail > 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 -c4 -u2 -N1 -f$srcdir/cfg3.testin 2>&1 |./ourtail > 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 -c4 -u2 -N1 -f$srcdir/cfg4.testin 2>&1 |./ourtail > 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 0000000..d49d207
--- /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 https://www.rsyslog.com/e/3003 ]
+rsyslogd: the last error occurred 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 0000000..7d7b594
--- /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 0000000..8a98eb5
--- /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 https://www.rsyslog.com/e/3003 ]
+rsyslogd: the last error occurred 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 0000000..b6d98c8
--- /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 0000000..5edd4ef
--- /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 https://www.rsyslog.com/e/2040 ]
+rsyslogd: the last error occurred in ./cfg3.testin, line 1
+rsyslogd: CONFIG ERROR: there are no active actions configured. Inputs will run, but no output whatsoever is created. [try https://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 0000000..9789d93
--- /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 0000000..04acf84
--- /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 0000000..b8694ad
--- /dev/null
+++ b/tests/cfg4.testin
@@ -0,0 +1,31 @@
+# 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
+# https://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.
+
+
+
+# ######### 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
+$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/check_relpEngineVersion.c b/tests/check_relpEngineVersion.c
new file mode 100644
index 0000000..69b6700
--- /dev/null
+++ b/tests/check_relpEngineVersion.c
@@ -0,0 +1,66 @@
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+/* only care about first two digits */
+void parseVersionNumberFromStr(char *pszIn, long* piMajor, long* piMinor, long* piSubMinor) {
+ char *p = pszIn;
+ while (*p) { // While there are more characters to process...
+ if ( isdigit(*p) || ( (*p=='-'||*p=='+') && isdigit(*(p+1)) )) {
+ if (*piMajor == 0) {
+ *piMajor = strtol(p, &p, 10); // Read number
+ } else if (*piMinor == 0) {
+ *piMinor = strtol(p, &p, 10); // Read number
+ } else {
+ *piSubMinor = strtol(p, &p, 10); // Read number
+ return;
+ }
+ } else {
+ p++;
+ }
+ }
+}
+
+int main(int argc __attribute__((unused)), char *argv[]__attribute__((unused)))
+{
+ long iRelpVerMajor = 0;
+ long iRelpVerMinor = 0;
+ long iRelpVerSubMinor = 0;
+ long iRelpCmpMajor = 0;
+ long iRelpCmpMinor = 0;
+ long iRelpCmpSubMinor = 0;
+
+#if defined(RELP_VERSION)
+ parseVersionNumberFromStr(RELP_VERSION, &iRelpVerMajor, &iRelpVerMinor, &iRelpVerSubMinor);
+ if (argc > 1) {
+ parseVersionNumberFromStr(argv[1], &iRelpCmpMajor, &iRelpCmpMinor, &iRelpCmpSubMinor);
+
+ // Compare Version numbers
+ if ( iRelpVerMajor > iRelpCmpMajor ||
+ ( iRelpVerMajor == iRelpCmpMajor &&
+ iRelpVerMinor > iRelpCmpMinor ) ||
+ ( iRelpVerMajor == iRelpCmpMajor &&
+ iRelpVerMinor == iRelpCmpMinor &&
+ iRelpVerSubMinor >= iRelpCmpSubMinor)
+ ) {
+ printf("RELP Version %ld.%ld.%ld OK (Requested Version %ld.%ld.%ld)\n",
+ iRelpVerMajor, iRelpVerMinor, iRelpVerSubMinor,
+ iRelpCmpMajor, iRelpCmpMinor, iRelpCmpSubMinor);
+ return 0;
+ } else {
+ printf("RELP Version %ld.%ld.%ld NOT OK (Requested Version %ld.%ld.%ld)\n",
+ iRelpVerMajor, iRelpVerMinor, iRelpVerSubMinor,
+ iRelpCmpMajor, iRelpCmpMinor, iRelpCmpSubMinor);
+ return 1;
+ }
+
+ } else {
+ printf("RELP Version %s\n", RELP_VERSION);
+ }
+ return 0;
+#else
+ printf("RELP Version unknown\n");
+ return 1;
+#endif
+}
diff --git a/tests/chkseq.c b/tests/chkseq.c
new file mode 100644
index 0000000..00674e9
--- /dev/null
+++ b/tests/chkseq.c
@@ -0,0 +1,249 @@
+/* Checks if a file consists of line of strictly monotonically
+ * increasing numbers. An expected start and end number may
+ * be set.
+ *
+ * Params
+ * -f<filename> file to process, if not given stdin is processed.
+ * -s<starting number> -e<ending number>
+ * default for s is 0. -e should be given (else it is also 0)
+ * -d may be specified, in which case duplicate messages are permitted.
+ * -m number of messages permitted to be missing without triggering a
+ * failure. This is necessary for some failover tests, where it is
+ * impossible to totally guard against messagt loss. By default, NO
+ * message is permitted to be lost.
+ * -T anticipate truncation (which means specified payload length may be
+ * more than actual payload (which may have been truncated)
+ * -i increment between messages (default: 1). Can be used for tests which
+ * intentionally leave consistent gaps in the message numbering.
+ *
+ * Part of the testbench for rsyslog.
+ *
+ * Copyright 2009-2018 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>
+#if defined(_AIX)
+ #include <unistd.h>
+#else
+ #include <getopt.h>
+#endif
+
+int main(int argc, char *argv[])
+{
+ FILE *fp;
+ int val;
+ int i;
+ int ret = 0;
+ int scanfOK;
+ int verbose = 0;
+ int bHaveExtraData = 0;
+ int bAnticipateTruncation = 0;
+ int dupsPermitted = 0;
+ int start = 0, end = 0;
+ int opt;
+ int lostok = 0; /* how many messages are OK to be lost? */
+ int nDups = 0;
+ int increment = 1;
+ int reachedEOF;
+ int edLen; /* length of extra data */
+ static char edBuf[500*1024]; /* buffer for extra data (pretty large to be on the save side...) */
+ static char ioBuf[sizeof(edBuf)+1024];
+ char *file = NULL;
+
+ while((opt = getopt(argc, argv, "i:e:f:ds:vm:ET")) != EOF) {
+ switch((char)opt) {
+ case 'f':
+ file = optarg;
+ break;
+ case 'd':
+ dupsPermitted = 1;
+ break;
+ case 'i':
+ increment = atoi(optarg);
+ break;
+ case 'e':
+ end = atoi(optarg);
+ break;
+ case 's':
+ start = atoi(optarg);
+ break;
+ case 'v':
+ ++verbose;
+ break;
+ case 'm':
+ lostok = atoi(optarg);
+ break;
+ case 'E':
+ bHaveExtraData = 1;
+ break;
+ case 'T':
+ bAnticipateTruncation = 1;
+ break;
+ default:printf("Invalid call of chkseq, optchar='%c'\n", opt);
+ printf("Usage: chkseq file -sstart -eend -d -E\n");
+ exit(1);
+ }
+ }
+
+ if(start > end) {
+ printf("start must be less than or equal end!\n");
+ exit(1);
+ }
+
+ if(verbose) {
+ printf("chkseq: start %d, end %d\n", start, end);
+ }
+
+ /* read file */
+ if(file == NULL) {
+ fp = stdin;
+ } else {
+ fp = fopen(file, "r");
+ }
+ if(fp == NULL) {
+ printf("error opening file '%s'\n", file);
+ perror(file);
+ exit(1);
+ }
+
+ for(i = start ; i <= end ; i += increment) {
+ if(bHaveExtraData) {
+ if(fgets(ioBuf, sizeof(ioBuf), fp) == NULL) {
+ scanfOK = 0;
+ } else {
+ scanfOK = sscanf(ioBuf, "%d,%d,%s\n", &val, &edLen, edBuf) == 3 ? 1 : 0;
+ }
+ if(edLen != (int) strlen(edBuf)) {
+ if (bAnticipateTruncation == 1) {
+ if (edLen < (int) strlen(edBuf)) {
+ printf("extra data length specified %d, but actually is %ld in"
+ " record %d (truncation was anticipated, but payload should"
+ " have been smaller than data-length, not larger)\n",
+ edLen, (long) strlen(edBuf), i);
+ exit(1);
+ }
+ } else {
+ printf("extra data length specified %d, but actually is %ld in record %d\n",
+ edLen, (long) strlen(edBuf), i);
+ exit(1);
+ }
+ }
+ } else {
+ if(fgets(ioBuf, sizeof(ioBuf), fp) == NULL) {
+ scanfOK = 0;
+ } else {
+ scanfOK = sscanf(ioBuf, "%d\n", &val) == 1 ? 1 : 0;
+ }
+ }
+ if(!scanfOK) {
+ printf("scanf error in index i=%d\n", i);
+ exit(1);
+ }
+ while(val > i && lostok > 0) {
+ --lostok;
+ printf("message %d missing (ok due to -m [now %d])\n", i, lostok);
+ ++i;
+ }
+ if(val != i) {
+ if(val == i - increment && dupsPermitted) {
+ --i;
+ ++nDups;
+ } else {
+ printf("read value %d, but expected value %d\n", val, i);
+ exit(1);
+ }
+ }
+ }
+
+ if(i - increment != end) {
+ printf("lastrecord does not match. file: %d, expected %d\n", i - increment, end);
+ exit(1);
+ }
+
+ int c = getc(fp);
+ if(c == EOF) {
+ reachedEOF = 1;
+ } else {
+ ungetc(c, fp);
+ /* if duplicates are permitted, we need to do a final check if we have duplicates at the
+ * end of file.
+ */
+ if(dupsPermitted) {
+ i = end;
+ while(!feof(fp)) {
+ if(bHaveExtraData) {
+ if(fgets(ioBuf, sizeof(ioBuf), fp) == NULL) {
+ scanfOK = 0;
+ } else {
+ scanfOK = sscanf(ioBuf, "%d,%d,%s\n", &val,
+ &edLen, edBuf) == 3 ? 1 : 0;
+ }
+ if(edLen != (int) strlen(edBuf)) {
+ if (bAnticipateTruncation == 1) {
+ if (edLen < (int) strlen(edBuf)) {
+ printf("extra data length specified %d, but "
+ "actually is %ld in record %d (truncation was"
+ " anticipated, but payload should have been "
+ "smaller than data-length, not larger)\n",
+ edLen, (long) strlen(edBuf), i);
+ exit(1);
+ }
+ } else {
+ printf("extra data length specified %d, but actually "
+ "is %ld in record %d\n",
+ edLen, (long) strlen(edBuf), i);
+ exit(1);
+ }
+ }
+ } else {
+ if(fgets(ioBuf, sizeof(ioBuf), fp) == NULL) {
+ scanfOK = 0;
+ } else {
+ scanfOK = sscanf(ioBuf, "%d\n", &val) == 1 ? 1 : 0;
+ }
+ }
+
+ if(val != i) {
+ reachedEOF = 0;
+ goto breakIF;
+ }
+ }
+ reachedEOF = feof(fp) ? 1 : 0;
+ } else {
+ reachedEOF = 0;
+ }
+ }
+
+breakIF:
+ if(nDups != 0)
+ printf("info: had %d duplicates (this is no error)\n", nDups);
+
+ if(!reachedEOF) {
+ printf("end of processing, but NOT end of file! First line of extra data is:\n");
+ for(c = fgetc(fp) ; c != '\n' && c != EOF ; c = fgetc(fp))
+ putchar(c);
+ putchar('\n');
+ exit(1);
+ }
+
+ exit(ret);
+}
diff --git a/tests/clickhouse-basic-vg.sh b/tests/clickhouse-basic-vg.sh
new file mode 100755
index 0000000..f51450b
--- /dev/null
+++ b/tests/clickhouse-basic-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/clickhouse-basic.sh
diff --git a/tests/clickhouse-basic.sh b/tests/clickhouse-basic.sh
new file mode 100755
index 0000000..0c3306d
--- /dev/null
+++ b/tests/clickhouse-basic.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# add 2018-12-07 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1
+generate_conf
+add_conf '
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+
+template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.basic (id, severity, facility, timestamp, ipaddress, tag, message) VALUES (%msg:F,58:2%, %syslogseverity%, %syslogfacility%, '
+add_conf "'%timereported:::date-unixtimestamp%', '%fromhost-ip%', '%syslogtag%', '%msg%')"
+add_conf '")
+
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443" bulkmode="off"
+ user="default" pwd="" template="outfmt")
+'
+
+clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.basic ( id Int32, severity Int8, facility Int8, timestamp DateTime, ipaddress String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id"
+
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+clickhouse-client --query="SELECT id, severity, facility, ipaddress, tag, message FROM rsyslog.basic" > $RSYSLOG_OUT_LOG
+
+clickhouse-client --query="DROP TABLE rsyslog.basic"
+export EXPECTED='0 7 20 127.0.0.1 tag msgnum:00000000:'
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/clickhouse-bulk-load-vg.sh b/tests/clickhouse-bulk-load-vg.sh
new file mode 100755
index 0000000..75ad35c
--- /dev/null
+++ b/tests/clickhouse-bulk-load-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/clickhouse-bulk-load.sh
diff --git a/tests/clickhouse-bulk-load.sh b/tests/clickhouse-bulk-load.sh
new file mode 100755
index 0000000..3f4099e
--- /dev/null
+++ b/tests/clickhouse-bulk-load.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# add 2018-12-07 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100000
+
+generate_conf
+add_conf '
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+
+template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.bulkLoad (id, ipaddress, message) VALUES (%msg:F,58:2%, '
+add_conf "'%fromhost-ip%', '%msg:F,58:2%')"
+add_conf '")
+
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443"
+ user="default" pwd="" template="outfmt")
+'
+
+clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.bulkLoad ( id Int32, ipaddress String, message String ) ENGINE = MergeTree() PARTITION BY ipaddress Order By id"
+
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+clickhouse-client --query="SELECT message FROM rsyslog.bulkLoad ORDER BY id" > $RSYSLOG_OUT_LOG
+
+clickhouse-client --query="DROP TABLE rsyslog.bulkLoad"
+seq_check 0 $(( NUMMESSAGES - 1 ))
+
+exit_test
diff --git a/tests/clickhouse-bulk-vg.sh b/tests/clickhouse-bulk-vg.sh
new file mode 100755
index 0000000..fbc77ba
--- /dev/null
+++ b/tests/clickhouse-bulk-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/clickhouse-bulk.sh
diff --git a/tests/clickhouse-bulk.sh b/tests/clickhouse-bulk.sh
new file mode 100755
index 0000000..297df36
--- /dev/null
+++ b/tests/clickhouse-bulk.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# add 2018-12-07 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10
+generate_conf
+add_conf '
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+
+template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.bulk (id, severity, facility, timestamp, ipaddress, tag, message) VALUES (%msg:F,58:2%, %syslogseverity%, %syslogfacility%, '
+add_conf "'%timereported:::date-unixtimestamp%', '%fromhost-ip%', '%syslogtag%', '%msg%')"
+add_conf '")
+
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443"
+ user="default" pwd="" template="outfmt")
+'
+
+clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.bulk ( id Int32, severity Int8, facility Int8, timestamp DateTime, ipaddress String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id"
+
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+clickhouse-client --query="SELECT id, severity, facility, ipaddress, tag, message FROM rsyslog.bulk ORDER BY id" > $RSYSLOG_OUT_LOG
+
+export EXPECTED='0 7 20 127.0.0.1 tag msgnum:00000000:
+1 7 20 127.0.0.1 tag msgnum:00000001:
+2 7 20 127.0.0.1 tag msgnum:00000002:
+3 7 20 127.0.0.1 tag msgnum:00000003:
+4 7 20 127.0.0.1 tag msgnum:00000004:
+5 7 20 127.0.0.1 tag msgnum:00000005:
+6 7 20 127.0.0.1 tag msgnum:00000006:
+7 7 20 127.0.0.1 tag msgnum:00000007:
+8 7 20 127.0.0.1 tag msgnum:00000008:
+9 7 20 127.0.0.1 tag msgnum:00000009:'
+cmp_exact $RSYSLOG_OUT_LOG
+
+clickhouse-client --query="DROP TABLE rsyslog.bulk"
+exit_test
diff --git a/tests/clickhouse-dflt-tpl.sh b/tests/clickhouse-dflt-tpl.sh
new file mode 100755
index 0000000..3224b86
--- /dev/null
+++ b/tests/clickhouse-dflt-tpl.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# add 2018-12-07 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1
+generate_conf
+add_conf '
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443" bulkmode="off"
+ user="default" pwd="")
+'
+
+clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.SystemEvents ( severity Int8, facility Int8, timestamp DateTime, hostname String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity order by tuple()"
+
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+clickhouse-client --query="SELECT * FROM rsyslog.SystemEvents FORMAT CSV" > $RSYSLOG_OUT_LOG
+
+clickhouse-client --query="DROP TABLE rsyslog.SystemEvents"
+content_check --regex '7,20,"20..-03-01 01:00:00","172.20.245.8","tag"," msgnum:00000000:"'
+
+exit_test
diff --git a/tests/clickhouse-errorfile.sh b/tests/clickhouse-errorfile.sh
new file mode 100755
index 0000000..6004861
--- /dev/null
+++ b/tests/clickhouse-errorfile.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2018-12-07 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+echo looks like clickhouse does no longer generate exceptions on error - skip until investigated
+exit 77
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.errorfile (id, severity, facility, timestamp, ipaddress, tag, message) VALUES (%msg:F,58:2%, %syslogseverity%, %syslogfacility%, '
+add_conf "'%timereported:::date-unixtimestamp%', '%fromhost-ip%', '%syslogtag%', '%msg%')"
+add_conf '")
+
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443"
+ user="default" pwd="" template="outfmt"
+ bulkmode="off" errorfile="'$RSYSLOG_OUT_LOG'")
+'
+
+clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.errorfile ( id Int32, severity Int8, facility Int8, timestamp DateTime, ipaddress String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id"
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:NoInteger\""
+shutdown_when_empty
+wait_shutdown
+
+content_check --regex "msgnum:NoInteger.*DB::Exception:"
+
+clickhouse-client --query="DROP TABLE rsyslog.errorfile"
+exit_test
diff --git a/tests/clickhouse-limited-batch.sh b/tests/clickhouse-limited-batch.sh
new file mode 100755
index 0000000..7f1fcd1
--- /dev/null
+++ b/tests/clickhouse-limited-batch.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2018-12-20 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100000
+
+generate_conf
+add_conf '
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+
+template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.limited (id, ipaddress, message) VALUES (%msg:F,58:2%, '
+add_conf "'%fromhost-ip%', '%msg:F,58:2%')"
+add_conf '")
+
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443"
+ user="default" pwd="" template="outfmt"
+ maxbytes="1k")
+'
+
+clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.limited ( id Int32, ipaddress String, message String ) ENGINE = MergeTree() PARTITION BY ipaddress Order By id"
+
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+clickhouse-client --query="SELECT message FROM rsyslog.limited ORDER BY id" > $RSYSLOG_OUT_LOG
+
+clickhouse-client --query="DROP TABLE rsyslog.limited"
+seq_check 0 $(( NUMMESSAGES - 1 ))
+
+exit_test
diff --git a/tests/clickhouse-load-vg.sh b/tests/clickhouse-load-vg.sh
new file mode 100755
index 0000000..e0e33eb
--- /dev/null
+++ b/tests/clickhouse-load-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/clickhouse-load.sh
diff --git a/tests/clickhouse-load.sh b/tests/clickhouse-load.sh
new file mode 100755
index 0000000..40e00b9
--- /dev/null
+++ b/tests/clickhouse-load.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2018-12-07 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+
+generate_conf
+add_conf '
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+
+template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.load (id, ipaddress, message) VALUES (%msg:F,58:2%, '
+add_conf "'%fromhost-ip%', '%msg:F,58:2%')"
+add_conf '")
+
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" usehttps="off"
+ user="default" pwd="" template="outfmt"
+ bulkmode="off")
+'
+
+clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.load ( id Int32, ipaddress String, message String ) ENGINE = MergeTree() PARTITION BY ipaddress Order By id"
+
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+clickhouse-client --query="SELECT message FROM rsyslog.load ORDER BY id" > $RSYSLOG_OUT_LOG
+
+clickhouse-client --query="DROP TABLE rsyslog.load"
+seq_check 0 $(( NUMMESSAGES - 1 ))
+
+exit_test
diff --git a/tests/clickhouse-retry-error.sh b/tests/clickhouse-retry-error.sh
new file mode 100755
index 0000000..d5dccff
--- /dev/null
+++ b/tests/clickhouse-retry-error.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# add 2018-12-31 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1
+generate_conf
+add_conf '
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+
+template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.retryerror (id, severity, message) VALUES (%msg:F,58:2%, %syslogseverity%, '
+add_conf "'%msg%')"
+add_conf '")
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost"
+ bulkmode="off" user="default" pwd=""
+ template="outfmt")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+
+content_check "omclickhouse: checkConn failed."
+
+exit_test
diff --git a/tests/clickhouse-select.sh b/tests/clickhouse-select.sh
new file mode 100755
index 0000000..0f5ccc3
--- /dev/null
+++ b/tests/clickhouse-select.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# add 2018-12-07 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1
+generate_conf
+add_conf '
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+
+template(name="outfmt" option.stdsql="on" type="string" string="SELECT * FROM rsyslog.select")
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443"
+ bulkmode="off" user="default" pwd=""
+ template="outfmt")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.select ( id Int32, severity Int8, facility Int8, timestamp DateTime, ipaddress String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id"
+
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+
+clickhouse-client --query="DROP TABLE rsyslog.select"
+content_check "omclickhouse: Message is no Insert query: Message suspended: SELECT * FROM rsyslog.select"
+
+exit_test
diff --git a/tests/clickhouse-start.sh b/tests/clickhouse-start.sh
new file mode 100755
index 0000000..200200c
--- /dev/null
+++ b/tests/clickhouse-start.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# This is not a real test, but a script to start clickhouse. It is
+# implemented as test so that we can start clickhouse at the time we need
+# it (do so via Makefile.am).
+# Copyright (C) 2018 Pascal Withopf and Adiscon GmbH
+# Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+set -x
+if [ "$CLICKHOUSE_START_CMD" == "" ]; then
+ exit_test # no start needed
+fi
+
+test_error_exit_handler() {
+ printf 'clickhouse startup failed, log is:\n'
+ $SUDO cat /var/log/clickhouse-server/clickhouse-server.err.log
+}
+
+printf 'starting clickhouse...\n'
+$CLICKHOUSE_START_CMD &
+sleep 10
+#wait_startup_pid /var/run/clickhouse-server/clickhouse-server.pid
+printf 'preparing clickhouse for testbench use...\n'
+$SUDO ${srcdir}/../devtools/prepare_clickhouse.sh
+clickhouse-client --query="select 1"
+rc=$?
+if [ $rc -ne 0 ]; then
+ printf 'clickhouse failed to start, exit code %d\n' $rc
+ error_exit 100
+fi
+printf 'done, clickhouse ready for testbench\n'
+exit_test
diff --git a/tests/clickhouse-stop.sh b/tests/clickhouse-stop.sh
new file mode 100755
index 0000000..7f132d8
--- /dev/null
+++ b/tests/clickhouse-stop.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# This is not a real test, but a script to stop clickhouse. It is
+# implemented as test so that we can stop clickhouse at the time we need
+# it (do so via Makefile.am).
+# Copyright (C) 2018 Pascal Withopf and Adiscon GmbH
+# Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+if [ "$CLICKHOUSE_STOP_CMD" == "" ]; then
+ exit_test
+fi
+
+clickhouse-client --query="DROP DATABASE rsyslog"
+sleep 1
+printf 'stopping clickhouse...\n'
+#$SUDO sed -n -r 's/PID: ([0-9]+\.*)/\1/p' /var/lib/clickhouse/status > /tmp/clickhouse-server.pid
+#$SUDO kill $($SUDO sed -n -r 's/PID: ([0-9]+\.*)/\1/p' /var/lib/clickhouse/status)
+eval $CLICKHOUSE_STOP_CMD
+sleep 1 # cosmetic: give clickhouse a chance to emit shutdown message
+exit_test
diff --git a/tests/clickhouse-wrong-insert-syntax.sh b/tests/clickhouse-wrong-insert-syntax.sh
new file mode 100755
index 0000000..7c3ae9e
--- /dev/null
+++ b/tests/clickhouse-wrong-insert-syntax.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# add 2018-12-07 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+echo looks like clickhouse does no longer generate exceptions on error - skip until investigated
+exit 77
+export NUMMESSAGES=1
+generate_conf
+add_conf '
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+
+template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.wrongInsertSyntax (id, severity, facility, timestamp, ipaddress, tag, message) VLUES (%msg:F,58:2%, %syslogseverity%, %syslogfacility%, '
+add_conf "'%timereported:::date-unixtimestamp%', '%fromhost-ip%', '%syslogtag%', '%msg%')"
+add_conf '")
+
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443"
+ user="default" pwd="" template="outfmt"
+ bulkmode="off" errorfile="'$RSYSLOG_OUT_LOG'")
+'
+
+clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.wrongInsertSyntax ( id Int32, severity Int8, facility Int8, timestamp DateTime, ipaddress String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id"
+
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+
+clickhouse-client --query="DROP TABLE rsyslog.wrongInsertSyntax"
+content_check "DB::Exception: Syntax error"
+exit_test
diff --git a/tests/clickhouse-wrong-quotation-marks.sh b/tests/clickhouse-wrong-quotation-marks.sh
new file mode 100755
index 0000000..618aafe
--- /dev/null
+++ b/tests/clickhouse-wrong-quotation-marks.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# add 2018-12-19 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+
+template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.quotation (id, severity, message) VALUES ( 1, '
+add_conf "%syslogseverity%, '%msg%')"
+add_conf '")
+
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost"
+ port="8443" bulkmode="off"
+ user="default" pwd="" template="outfmt")
+'
+
+clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.quotation ( id Int32, severity Int8, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id"
+
+startup
+tcpflood -m1 -M "\"<130>Mar 10 01:00:00 172.20.245.8 tag:it's a test\""
+shutdown_when_empty
+wait_shutdown
+clickhouse-client --query="SELECT id, severity, message FROM rsyslog.quotation" > $RSYSLOG_OUT_LOG
+
+export EXPECTED="1 2 it\\'s a test"
+cmp_exact $RSYSLOG_OUT_LOG
+
+clickhouse-client --query="DROP TABLE rsyslog.quotation"
+exit_test
diff --git a/tests/clickhouse-wrong-template-option.sh b/tests/clickhouse-wrong-template-option.sh
new file mode 100755
index 0000000..3c9083f
--- /dev/null
+++ b/tests/clickhouse-wrong-template-option.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2018-12-19 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1
+generate_conf
+add_conf '
+module(load="../plugins/omclickhouse/.libs/omclickhouse")
+
+template(name="outfmt" type="string" string="INSERT INTO rsyslog.template (id, severity, facility, timestamp, ipaddress, tag, message) VALUES (%msg:F,58:2%, %syslogseverity%, %syslogfacility%, '
+add_conf "'%timereported:::date-unixtimestamp%', '%fromhost-ip%', '%syslogtag%', '%msg%')"
+add_conf '")
+
+
+:syslogtag, contains, "tag" action(type="omclickhouse" server="localhost"
+ usehttps="off" bulkmode="off"
+ user="default" pwd="" template="outfmt")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.template ( id Int32, severity Int8, facility Int8, timestamp DateTime, ipaddress String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id"
+
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+
+clickhouse-client --query="DROP TABLE rsyslog.template"
+content_check "you have to specify the SQL or stdSQL option in your template!"
+
+exit_test
diff --git a/tests/complex1.sh b/tests/complex1.sh
new file mode 100755
index 0000000..a51d332
--- /dev/null
+++ b/tests/complex1.sh
@@ -0,0 +1,132 @@
+#!/bin/bash
+# This is a rather complex test that runs a number of features together.
+#
+# added 2010-03-16 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on all flavors of Solaris."
+export NUMMESSAGES=40000
+export RSYSLOG_PORT2="$(get_free_port)"
+export RSYSLOG_PORT3="$(get_free_port)"
+generate_conf
+echo ports: $TCPFLOOD_PORT $RSYSLOG_PORT2 $RSYSLOG_PORT3
+add_conf '
+$MaxMessageSize 10k
+
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+
+$template outfmt,"%msg:F,58:3%,%msg:F,58:4%,%msg:F,58:5%\n"
+$template dynfile,"'$RSYSLOG_DYNNAME'.out.%inputname%.%msg:F,58:2%.log.Z"
+
+## RULESET with listener
+$Ruleset R13514
+# queue params:
+$ActionQueueTimeoutShutdown 60000
+$ActionQueueTimeoutEnqueue 20000
+$ActionQueueSize 5000
+$ActionQueueSaveOnShutdown on
+$ActionQueueHighWaterMark 4900
+$ActionQueueLowWaterMark 3500
+$ActionQueueType FixedArray
+$ActionQueueWorkerThreads 1
+# action params:
+$OMFileFlushOnTXEnd off
+$OMFileZipLevel 6
+$DynaFileCacheSize 4
+$omfileFlushInterval 1
+*.* ?dynfile;outfmt
+action(type="omfile" file ="'$RSYSLOG_DYNNAME'.countfile")
+# listener
+$InputTCPServerInputName '$TCPFLOOD_PORT'
+$InputTCPServerBindRuleset R13514
+$InputTCPServerRun '$TCPFLOOD_PORT'
+
+
+## RULESET with listener
+$Ruleset R_PORT2
+# queue params:
+$ActionQueueTimeoutShutdown 60000
+$ActionQueueTimeoutEnqueue 20000
+$ActionQueueSize 5000
+$ActionQueueSaveOnShutdown on
+$ActionQueueHighWaterMark 4900
+$ActionQueueLowWaterMark 3500
+$ActionQueueType FixedArray
+$ActionQueueWorkerThreads 1
+# action params:
+$OMFileFlushOnTXEnd off
+$OMFileZipLevel 6
+$OMFileIOBufferSize 256k
+$DynaFileCacheSize 4
+$omfileFlushInterval 1
+*.* ?dynfile;outfmt
+action(type="omfile" file ="'$RSYSLOG_DYNNAME'.countfile")
+# listener
+$InputTCPServerInputName '$RSYSLOG_PORT2'
+$InputTCPServerBindRuleset R_PORT2
+$InputTCPServerRun '$RSYSLOG_PORT2'
+
+
+
+## RULESET with listener
+$Ruleset R_PORT3
+# queue params:
+$ActionQueueTimeoutShutdown 60000
+$ActionQueueTimeoutEnqueue 20000
+$ActionQueueSize 5000
+$ActionQueueSaveOnShutdown on
+$ActionQueueHighWaterMark 4900
+$ActionQueueLowWaterMark 3500
+$ActionQueueType FixedArray
+$ActionQueueWorkerThreads 1
+# action params:
+$OMFileFlushOnTXEnd off
+$OMFileZipLevel 6
+$OMFileIOBufferSize 256k
+$DynaFileCacheSize 4
+$omfileFlushInterval 1
+*.* ?dynfile;outfmt
+action(type="omfile" file ="'$RSYSLOG_DYNNAME'.countfile")
+# listener
+$InputTCPServerInputName '$RSYSLOG_PORT3'
+$InputTCPServerBindRuleset R_PORT3
+$InputTCPServerRun '$RSYSLOG_PORT3'
+'
+
+count_function() {
+ # TODO: try to make this work on the compressed files, only
+ # idea does not work as we miss end-of-zip record
+ # leaving it commented out if we see we should really switch to that
+ # method; if we do not need for an extended period of time, this shall
+ # be removed -- rgerhards, 2018-12-19
+ #mkdir "$RSYSLOG_DYNNAME.countwrk"
+ #cp $RSYSLOG_DYNNAME.out.*.log.Z "$RSYSLOG_DYNNAME.countwrk"
+ #cd "$RSYSLOG_DYNNAME.countwrk"
+ #gunzip $RSYSLOG_DYNNAME.out.*.log.Z
+ #printf '%d' $(cat $RSYSLOG_DYNNAME.out.*.log | wc -l)
+ #cd ..
+ #rm -rf "$RSYSLOG_DYNNAME.countwrk"
+
+ # now the real - simple - code:
+ printf '%d' $(wc -l < $RSYSLOG_DYNNAME.countfile)
+}
+
+startup
+# send 40,000 messages of 400 bytes plus header max, via three dest ports
+export TCPFLOOD_PORT="$TCPFLOOD_PORT:$RSYSLOG_PORT2:$RSYSLOG_PORT3"
+tcpflood -m$NUMMESSAGES -rd400 -P129 -f5 -n3 -c15 -i1
+
+# note: we have FlushOnTX=off, so we will not see the last block inside the file;
+# as such we wait until a "sufficiently large" number of messages has arrived and
+# hope that shutdown_when_empty gets us toward the rest. It's still a bit racy,
+# but should be better than without the wait_file_lines.
+wait_file_lines --delay 1000 --count-function count_function DUMMY-filename $((NUMMESSAGES - 1500))
+shutdown_when_empty
+wait_shutdown
+ls $RSYSLOG_DYNNAME.out.*.log.Z
+gunzip $RSYSLOG_DYNNAME.out.*.log.Z
+cat $RSYSLOG_DYNNAME.out.*.log > $RSYSLOG_OUT_LOG
+seq_check 1 $NUMMESSAGES -E
+exit_test
diff --git a/tests/compresssp-stringtpl.sh b/tests/compresssp-stringtpl.sh
new file mode 100755
index 0000000..957cede
--- /dev/null
+++ b/tests/compresssp-stringtpl.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# addd 2016-03-22 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:::compressSPACE%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+startup
+# we need to generate a file, because otherwise our multiple spaces
+# do not survive the execution paths through the shell
+echo "<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000 test test test" >$RSYSLOG_DYNNAME.tmp
+tcpflood -I $RSYSLOG_DYNNAME.tmp
+rm $RSYSLOG_DYNNAME.tmp
+#tcpflood -m1 -M"\"<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000 test test test\""
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="msgnum:0000000 test test test"
+cmp_exact
+exit_test
diff --git a/tests/compresssp.sh b/tests/compresssp.sh
new file mode 100755
index 0000000..3261568
--- /dev/null
+++ b/tests/compresssp.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# addd 2016-03-22 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="list") {
+ property(name="msg" compressSpace="on")
+ constant(value="\n")
+}
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+startup
+# we need to generate a file, because otherwise our multiple spaces
+# do not survive the execution paths through the shell
+echo "<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000 test test test" >$RSYSLOG_DYNNAME.tmp
+tcpflood -I $RSYSLOG_DYNNAME.tmp
+rm $RSYSLOG_DYNNAME.tmp
+#tcpflood -m1 -M"\"<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000 test test test\""
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="msgnum:0000000 test test test"
+cmp_exact
+exit_test
diff --git a/tests/config_enabled-off.sh b/tests/config_enabled-off.sh
new file mode 100755
index 0000000..8cc2777
--- /dev/null
+++ b/tests/config_enabled-off.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# check disabling a config construct via config.enable. Most
+# importantly ensure that it does not emit any error messages
+# for object parameters.
+# addd 2019-05-09 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile" file="/tmp/notyet.txt" tag="testing-tag" config.enabled="off")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check 'imfile: no files configured'
+check_not_present 'parameter .* not known'
+exit_test
diff --git a/tests/config_enabled-on.sh b/tests/config_enabled-on.sh
new file mode 100755
index 0000000..11e5f8f
--- /dev/null
+++ b/tests/config_enabled-on.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# check disabling a config construct via config.enable. Most
+# importantly ensure that it does not emit any error messages
+# for object parameters.
+# addd 2019-12-09 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile" file="/tmp/notyet.txt" tag="testing-tag" config.enabled="on" invalid.param="error")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check 'imfile: on startup file'
+content_check --regex 'parameter.*invalid.param.*not known'
+check_not_present 'parameter.*config.enabled.*not known'
+exit_test
diff --git a/tests/config_multiple_include.sh b/tests/config_multiple_include.sh
new file mode 100755
index 0000000..534640c
--- /dev/null
+++ b/tests/config_multiple_include.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# check nested include processing works correctly (and keeps proper order)
+# added 2021-03-29 by Rainer Gerhards; Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+# Note: we need to pre-build the second level include file name because
+# under "make distchek" we have a different environment and with the
+# current rsyslog implemenation, we can only have a single environment
+# variable in an `echo $VAR` block. This we cannot combine the include
+# file name inside the config include without this trick.
+export INCLUDE2="${srcdir}/testsuites/include-std2-omfile-action.conf"
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum:" then {
+ include(file="'${srcdir}'/testsuites/include-std1-omfile-actio*.conf")
+ continue
+}
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+ls -l "$RSYSLOG2_OUT_LOG"
+if [ -f "$RSYSLOG2_OUT_LOG" ]; then
+ printf '\nERROR: file %s exists, but should have stopped by inner include\n' "$RSYSLOG2_OUT_LOG"
+ printf 'This looks like a problem with order of include file processing.\n\n'
+ error_exit 1
+fi
+exit_test
diff --git a/tests/config_output-o-option.sh b/tests/config_output-o-option.sh
new file mode 100755
index 0000000..65c30ea
--- /dev/null
+++ b/tests/config_output-o-option.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# check that the -o command line option works
+# added 2019-04-26 by Rainer Gerhards; Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum:" then {
+ include(file="'${srcdir}'/testsuites/include-std-omfile-actio*.conf")
+ continue
+}
+'
+../tools/rsyslogd -N1 -f${TESTCONF_NM}.conf -o$RSYSLOG_DYNNAME.fullconf -M../runtime/.libs:../.libs
+content_check 'if $msg contains "msgnum:" then' $RSYSLOG_DYNNAME.fullconf
+content_check 'action(type="omfile"' $RSYSLOG_DYNNAME.fullconf
+content_check --regex "BEGIN CONFIG: .*include-std-omfile-action.conf" $RSYSLOG_DYNNAME.fullconf
+exit_test
diff --git a/tests/da-mainmsg-q.sh b/tests/da-mainmsg-q.sh
new file mode 100755
index 0000000..386fa08
--- /dev/null
+++ b/tests/da-mainmsg-q.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# Test for DA mode on the main message queue
+# This test checks if DA mode operates correctly. To do so,
+# it uses a small in-memory queue size, so that DA mode is initiated
+# rather soon, and disk spooling used. There is some uncertainty (based
+# on machine speeds), but in general the test should work rather well.
+# We add a few messages after the initial run, just so that we can
+# check everything recovers from DA mode correctly.
+# added 2009-04-22 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# set spool locations and switch queue to disk assisted mode
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+$MainMsgQueueSize 200 # this *should* trigger moving on to DA mode...
+# note: we must set QueueSize sufficiently high, so that 70% (light delay mark)
+# is high enough above HighWatermark!
+$MainMsgQueueHighWatermark 80
+$MainMsgQueueLowWatermark 40
+$MainMsgQueueFilename mainq
+$MainMsgQueueType linkedlist
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+
+# part1: send first 50 messages (in memory, only)
+injectmsg 0 50
+wait_file_lines $RSYSLOG_OUT_LOG 50 # let queue drain for this test case
+
+# part 2: send bunch of messages. This should trigger DA mode
+injectmsg 50 2000
+ls -l ${RSYSLOG_DYNNAME}.spool # for manual review
+wait_file_lines $RSYSLOG_OUT_LOG 2050 # wait to ensure DA queue is "empty"
+
+# send another handful
+injectmsg 2050 50
+
+shutdown_when_empty
+wait_shutdown
+seq_check 0 2099
+exit_test
diff --git a/tests/da-queue-persist.sh b/tests/da-queue-persist.sh
new file mode 100755
index 0000000..e5d9ced
--- /dev/null
+++ b/tests/da-queue-persist.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# Test for DA queue data persisting at shutdown. The
+# plan is to start an instance, emit some data, do a relatively
+# fast shutdown and then re-start the engine to process the
+# remaining data.
+# added 2019-05-08 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10000
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+main_queue(queue.type="linkedList" queue.filename="mainq"
+ queue.timeoutShutdown="1" queue.saveonshutdown="on")
+
+module(load="../plugins/omtesting/.libs/omtesting")
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum:" then
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+else
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.othermsg")
+
+$IncludeConfig '${RSYSLOG_DYNNAME}'work-delay.conf
+'
+
+# prepare config
+echo "*.* :omtesting:sleep 0 1000" > ${RSYSLOG_DYNNAME}work-delay.conf
+
+startup
+injectmsg 0 $NUMMESSAGES
+shutdown_immediate
+wait_shutdown
+check_mainq_spool
+
+echo "Enter phase 2, rsyslogd restart"
+# note: we may have some few duplicates!
+echo "#" > ${RSYSLOG_DYNNAME}work-delay.conf
+wait_seq_check_with_dupes() {
+ wait_seq_check 0 $((NUMMESSAGES - 1)) -d
+}
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check_with_dupes
+startup
+shutdown_when_empty
+seq_check 0 $((NUMMESSAGES - 1)) -d
+content_check "queue files exist on disk, re-starting with" $RSYSLOG_DYNNAME.othermsg
+exit_test
diff --git a/tests/daqueue-dirty-shutdown.sh b/tests/daqueue-dirty-shutdown.sh
new file mode 100755
index 0000000..c8de84b
--- /dev/null
+++ b/tests/daqueue-dirty-shutdown.sh
@@ -0,0 +1,116 @@
+#!/bin/bash
+# This test simulates the case where the OS force-terminates rsyslog
+# before it completely finishes persisting the queue to disk. Obviously,
+# there is some data loss involved, but rsyslog should try to limit it.
+# Most importantly, a .qi file needs to be written at "save" places, so that
+# at least the queue is kind of readable.
+# To simulate the error condition, we create a DA queue with a large memory
+# part and fill it via injectmsg (do NOT use tcpflood, as this would add
+# complexity of TCP window etc to the reception of messages - injectmsg is
+# synchronous, so we do not have anything in flight after it terminates).
+# We have a blocking action which prevents actual processing of any of the
+# injected messages. We then inject a large number of messages, but only
+# few above the number the memory part of the disk can hold. So the disk queue
+# begins to get used. Once injection is done, we terminate rsyslog in the
+# regular way, which will cause the memory part of the queue to be written
+# out. After a relatively short period, we kill -9 rsyslogd, so that it
+# does not have any chance to fully persists its state (this actually is
+# what happens when force-terminated by the OS).
+# Then, we check that at a minimum the .qi file exists.
+# Copyright (C) 2016 by Rainer Gerhards
+# Released under ASL 2.0
+
+#uncomment the following if you want a log for step 1 of this test
+#export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+#export RSYSLOG_DEBUGLOG="log"
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omtesting/.libs/omtesting")
+
+# set spool locations and switch queue to disk-only mode
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+main_queue(queue.filename="mainq" queue.saveonshutdown="on"
+ queue.timeoutshutdown="1" queue.maxfilesize="1m"
+ queue.timeoutworkerthreadshutdown="500" queue.size="200000"
+ )
+
+:msg, contains, "msgnum:" :omtesting:sleep 10 0
+'
+startup
+injectmsg 0 210000
+echo spool files immediately before shutdown:
+ls ${RSYSLOG_DYNNAME}.spool
+shutdown_immediate # shut down without the ability to fully persist state
+./msleep 750 # simulate an os timeout (let it run a *very short* bit, else it's done ;))
+echo spool files immediately after shutdown \(but before kill\):
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+
+. $srcdir/diag.sh kill-immediate # do not give it sufficient time to shutdown
+wait_shutdown
+rm -f $RSYSLOG_PIDBASE.pid # as we kill, rsyslog does not itself cleanup the pid file
+
+echo spool files after kill:
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+if [ ! -f ${RSYSLOG_DYNNAME}.spool/mainq.qi ]; then
+ echo "FAIL: .qi file does not exist!"
+ error_exit 1
+fi
+
+echo .qi file contents:
+cat ${RSYSLOG_DYNNAME}.spool/mainq.qi
+
+
+# We now restart rsyslog and make sure it'll clean up the disk queue.
+# So far, we cannot reliably detect if the data is properly shuffled
+# over, but that's a moot point anyhow because we expect to loss
+# (large) amounts of the data. In later stages, we however may verify
+
+#uncomment the following if you want a log for step 2 of this test
+#export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+#export RSYSLOG_DEBUGLOG="log2"
+
+printf 'RSYSLOG RESTART\n\n'
+# special case: we need to preserve our dynamic settings, as generate_conf
+# overwrites them. TODO: handle this in diag.sh
+RSYSLOG_DYNNAME_SAVE="$RSYSLOG_DYNNAME"
+RSYSLOG_OUT_LOG_SAVE="$RSYSLOG_OUT_LOG"
+generate_conf
+RSYSLOG_OUT_LOG="$RSYSLOG_OUT_LOG_SAVE"
+RSYSLOG_DYNNAME="$RSYSLOG_DYNNAME_SAVE"
+add_conf '
+module(load="../plugins/omtesting/.libs/omtesting")
+
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+main_queue(queue.filename="mainq" queue.saveonshutdown="on"
+ queue.maxfilesize="1m" # note: now regular shutdown timeout!
+ queue.timeoutworkerthreadshutdown="500" queue.size="200000"
+ )
+
+$template outfmt,"%msg:F,58:2%\n"
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+#wait_queueempty
+#echo existing queue empty, injecting new data
+#injectmsg 1000000 1000
+shutdown_when_empty
+wait_shutdown
+
+# now the spool directory must be empty
+spoolFiles=$(ls ${RSYSLOG_DYNNAME}.spool/)
+
+if [[ ! -z $spoolFiles ]]; then
+ echo "FAIL: spool directory is not empty!"
+ ls -l ${RSYSLOG_DYNNAME}.spool
+ error_exit 1
+fi
+
+# check if we got at least some data
+if [ ! -f $RSYSLOG_OUT_LOG ]; then
+ echo "FAIL: no output data gathered (no ${RSYSLOG_OUT_LOG})!"
+ error_exit 1
+fi
+exit_test
diff --git a/tests/daqueue-invld-qi.sh b/tests/daqueue-invld-qi.sh
new file mode 100755
index 0000000..94d6e72
--- /dev/null
+++ b/tests/daqueue-invld-qi.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on all flavors of Solaris."
+
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 1
+$MainMsgQueueSaveOnShutdown on
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$ModLoad ../plugins/omtesting/.libs/omtesting
+
+# set spool locations and switch queue to disk-only mode
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+$MainMsgQueueFilename mainq
+$IncludeConfig '${RSYSLOG_DYNNAME}'work-queuemode.conf
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+
+$IncludeConfig '${RSYSLOG_DYNNAME}'work-delay.conf
+'
+#export RSYSLOG_DEBUG="debug nologfuncflow nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="log"
+
+# prepare config
+echo \$MainMsgQueueType LinkedList > ${RSYSLOG_DYNNAME}work-queuemode.conf
+echo "*.* :omtesting:sleep 0 1000" > ${RSYSLOG_DYNNAME}work-delay.conf
+
+# inject 10000 msgs, so that DO hit the high watermark
+startup
+injectmsg 0 10000
+shutdown_immediate
+wait_shutdown
+check_mainq_spool
+./mangle_qi -d -q ${RSYSLOG_DYNNAME}.spool/mainq.qi > tmp.qi
+mv tmp.qi ${RSYSLOG_DYNNAME}.spool/mainq.qi
+
+echo "Enter phase 2, rsyslogd restart"
+
+# restart engine and have rest processed
+#remove delay
+echo "#" > ${RSYSLOG_DYNNAME}work-delay.conf
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 9999 -d
+exit_test
diff --git a/tests/daqueue-persist-drvr.sh b/tests/daqueue-persist-drvr.sh
new file mode 100755
index 0000000..ec5c1af
--- /dev/null
+++ b/tests/daqueue-persist-drvr.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+# Test for queue data persisting at shutdown. The
+# plan is to start an instance, emit some data, do a relatively
+# fast shutdown and then re-start the engine to process the
+# remaining data.
+# added 2009-05-27 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+# uncomment for debugging support:
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 1
+$MainMsgQueueSaveOnShutdown on
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$ModLoad ../plugins/omtesting/.libs/omtesting
+
+# set spool locations and switch queue to disk-only mode
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+$MainMsgQueueFilename mainq
+$IncludeConfig '${RSYSLOG_DYNNAME}'work-queuemode.conf
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+
+$IncludeConfig '${RSYSLOG_DYNNAME}'work-delay.conf
+'
+
+#export RSYSLOG_DEBUG="debug nologfuncflow nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="log"
+
+# prepare config
+echo \$MainMsgQueueType $1 > ${RSYSLOG_DYNNAME}work-queuemode.conf
+echo "*.* :omtesting:sleep 0 1000" > ${RSYSLOG_DYNNAME}work-delay.conf
+
+# inject 10000 msgs, so that DO hit the high watermark
+startup
+injectmsg 0 10000
+shutdown_immediate
+wait_shutdown
+check_mainq_spool
+
+echo "Enter phase 2, rsyslogd restart"
+
+# restart engine and have rest processed
+#remove delay
+echo "#" > ${RSYSLOG_DYNNAME}work-delay.conf
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 9999
+exit_test
diff --git a/tests/daqueue-persist.sh b/tests/daqueue-persist.sh
new file mode 100755
index 0000000..9499a06
--- /dev/null
+++ b/tests/daqueue-persist.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Test for queue data persisting at shutdown. We use the actual driver
+# to carry out multiple tests with different queue modes
+# added 2009-05-27 by Rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo \[daqueue-persist.sh\]: test data persisting at shutdown
+echo TEST is currently DISABLE because it is unstable
+exit 77
+echo mode linkedList
+$srcdir/daqueue-persist-drvr.sh LinkedList
+echo mode fixedArray
+$srcdir/daqueue-persist-drvr.sh FixedArray
+# the disk test should not fail, however, the config is extreme and using
+# it more or less is a config error
+echo Disk
+$srcdir/daqueue-persist-drvr.sh Disk
+# we do not test Direct mode because this absolute can not work in direct mode
+# (maybe we should do a fail-type of test?)
diff --git a/tests/diag.sh b/tests/diag.sh
new file mode 100755
index 0000000..c35edb0
--- /dev/null
+++ b/tests/diag.sh
@@ -0,0 +1,2946 @@
+#!/bin/bash
+#
+# this shell script provides commands to the common diag system. It enables
+# test scripts to wait for certain conditions and initiate certain actions.
+# needs support in config file.
+# NOTE: this file should be included with ". diag.sh", as it otherwise is
+# not always able to convey back states to the upper-level test driver
+# begun 2009-05-27 by rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+#
+# This file can be customized to environment specifics via environment
+# variables:
+# SUDO either blank, or the command to use for sudo (usually "sudo").
+# This env var is sometimes used to increase the chance that we
+# get extra information, e.g. when trying to analyze running
+# processes. Bottom line: if sudo is possible and you are OK with
+# the testbench utilizing this, use
+# export SUDO=sudo
+# to activate the extra functionality.
+# RS_SORTCMD Sort command to use (must support $RS_SORT_NUMERIC_OPT option). If unset,
+# "sort" is used. E.g. Solaris needs "gsort"
+# RS_SORT_NUMERIC_OPT option to use for numerical sort, If unset "-g" is used.
+# RS_CMPCMD cmp command to use. If unset, "cmd" is used.
+# E.g. Solaris needs "gcmp"
+# RS_HEADCMD head command to use. If unset, "head" is used.
+# E.g. Solaris needs "ghead"
+# RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT
+# global input timeout shutdown, default 60000 (60) sec. This should
+# only be set specifically if there is good need to do so, e.g. if
+# a test needs to timeout.
+# USE_VALGRIND if set to "YES", the test will be run under valgrind control, with
+# "default" settings (memcheck including leak check, termination on error).
+# This permits to have valgrind and non-valgrind versions of the same test
+# without the need to write it twice: just have a 2-liner -vg.sh which
+# does:
+# export USE_VALGRIND="YES"
+# source original-test.sh
+# sample can be seen in imjournal-basic[.vg].sh
+# You may also use USE_VALGRIND="YES-NOLEAK" to request valgrind without
+# leakcheck (this sometimes is needed).
+# ABORT_ALL_ON_TEST_FAIL
+# if set to "YES" and one test fails, all others are not executed but skipped.
+# This is useful in long-running CI jobs where we are happy with seeing the
+# first failure (to save time).
+#
+#
+# EXIT STATES
+# 0 - ok
+# 1 - FAIL
+# 77 - SKIP
+# 100 - Testbench failure
+export TB_ERR_TIMEOUT=101
+# 177 - internal state: test failed, but in a way that makes us strongly believe
+# this is caused by environment. This will lead to exit 77 (SKIP), but report
+# the failure if failure reporting is active
+
+# environment variables:
+# USE_AUTO_DEBUG "on" --> enables automatic debugging, anything else
+# turns it off
+
+# diag system internal environment variables
+# these variables are for use by test scripts - they CANNOT be
+# overridden by the user
+# TCPFLOOD_EXTRA_OPTS enables to set extra options for tcpflood, usually
+# used in tests that have a common driver where it
+# is too hard to set these options otherwise
+# CONFIG
+export ZOOPIDFILE="$(pwd)/zookeeper.pid"
+
+#valgrind="valgrind --malloc-fill=ff --free-fill=fe --log-fd=1"
+#valgrind="valgrind --tool=callgrind" # for kcachegrind profiling
+
+# **** use the line below for very hard to find leaks! *****
+#valgrind="valgrind --leak-check=full --show-leak-kinds=all --malloc-fill=ff --free-fill=fe --log-fd=1"
+
+#valgrind="valgrind --tool=drd --log-fd=1"
+#valgrind="valgrind --tool=helgrind --log-fd=1 --suppressions=$srcdir/linux_localtime_r.supp --gen-suppressions=all"
+#valgrind="valgrind --tool=exp-ptrcheck --log-fd=1"
+#set -o xtrace
+#export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+#export RSYSLOG_DEBUGLOG="log"
+TB_TIMEOUT_STARTSTOP=400 # timeout for start/stop rsyslogd in tenths (!) of a second 400 => 40 sec
+# note that 40sec for the startup should be sufficient even on very slow machines. we changed this from 2min on 2017-12-12
+TB_TEST_TIMEOUT=90 # number of seconds after which test checks timeout (eg. waits)
+TB_TEST_MAX_RUNTIME=${TEST_MAX_RUNTIME:-580} # maximum runtime in seconds for a test;
+ # default TEST_MAX_RUNTIME e.g. for long-running tests or special
+ # testbench use. Testbench will abort test
+ # after that time (iff it has a chance to, not strictly enforced)
+ # Note: 580 is slightly below the rsyslog-ci required max non-stdout writing timeout
+ # This is usually at 600 (10 minutes) and processes will be force-terminated if they
+ # go over it. This is especially bad because we do not receive notifications in this
+ # case.
+export RSYSLOG_DEBUG_TIMEOUTS_TO_STDERR="on" # we want to know when we loose messages due to timeouts
+if [ "$TESTTOOL_DIR" == "" ]; then
+ export TESTTOOL_DIR="${srcdir:-.}"
+fi
+
+# newer functionality is preferably introduced via bash functions
+# rgerhards, 2018-07-03
+rsyslog_testbench_test_url_access() {
+ local missing_requirements=
+ if ! hash curl 2>/dev/null ; then
+ missing_requirements="'curl' is missing in PATH; Make sure you have cURL installed! Skipping test ..."
+ fi
+
+ if [ -n "${missing_requirements}" ]; then
+ printf '%s\n' "${missing_requirements}"
+ exit 77
+ fi
+
+ local http_endpoint="$1"
+ if ! curl --fail --max-time 30 "${http_endpoint}" 1>/dev/null 2>&1; then
+ echo "HTTP endpoint '${http_endpoint}' is not reachable. Skipping test ..."
+ exit 77
+ else
+ echo "HTTP endpoint '${http_endpoint}' is reachable! Starting test ..."
+ fi
+}
+
+# function to skip a test on a specific platform
+# $1 is what we check in uname, $2 (optional) is a reason message
+skip_platform() {
+ if [ "$(uname)" == "$1" ]; then
+ printf 'platform is "%s" - test does not work under "%s"\n' "$(uname)" "$1"
+ if [ "$2" != "" ]; then
+ printf 'reason: %s\n' "$2"
+ fi
+ exit 77
+ fi
+
+}
+
+# function to skip a test if TSAN is enabled
+# This is necessary as TSAN does not properly handle thread creation
+# after fork() - which happens regularly in rsyslog if backgrounding
+# is activated.
+# $1 is the reason why TSAN is not supported
+# note: we depend on CFLAGS to properly reflect build options (what
+# usually is the case when the testbench is run)
+skip_TSAN() {
+ if [[ "$CFLAGS" == *"sanitize=thread"* ]]; then
+ printf 'test incompatible with TSAN because of %s\n' "$1"
+ exit 77
+ fi
+}
+
+
+# a consistent format to output testbench timestamps
+tb_timestamp() {
+ printf '%s[%s] ' "$(date +%H:%M:%S)" "$(( $(date +%s) - TB_STARTTEST ))"
+}
+
+# override the test timeout, but only if the new value is higher
+# than the previous one. This is necessary for slow test systems
+# $1 is timeout in seconds
+override_test_timeout() {
+ if [ "${1:=0}" == "" ]; then
+ printf 'FAIL: invalid testbench call, override_test_timeout needs value\n'
+ error_exit 100
+ fi
+ if [ "$1" -gt "$TB_TEST_TIMEOUT" ]; then
+ TB_TEST_TIMEOUT=$1
+ printf 'info: TB_TEST_TIMEOUT increased to %s\n' "$TB_TEST_TIMEOUT"
+ fi
+}
+
+# set special tests status. States ($1) are:
+# unreliable -- as the name says, test does not work reliably; $2 must be github issue URL
+# depending on CI configuration, "unreliable" tests are skipped and not failed
+# or not executed at all. Test reports may also be amended to github issue.
+test_status() {
+ if [ "$1" == "unreliable" ]; then
+ if [ "$2" == "" ]; then
+ printf 'TESTBENCH_ERROR: github issue URL must be given\n'
+ error_exit 100
+ fi
+ export TEST_STATUS="$1"
+ export TEST_GITHUB_ISSUE="$2"
+ else
+ printf 'TESTBENCH_ERROR: test_status "%s" unknown\n' "$1"
+ error_exit 100
+ fi
+}
+
+
+setvar_RS_HOSTNAME() {
+ printf '### Obtaining HOSTNAME (prerequisite, not actual test) ###\n'
+ generate_conf ""
+ add_conf 'module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template hostname,"%hostname%"
+local0.* ./'${RSYSLOG_DYNNAME}'.HOSTNAME;hostname
+'
+ rm -f "${RSYSLOG_DYNNAME}.HOSTNAME"
+ startup ""
+ tcpflood -m1 -M "\"<128>\""
+ shutdown_when_empty
+ wait_shutdown ""
+ export RS_HOSTNAME="$(cat ${RSYSLOG_DYNNAME}.HOSTNAME)"
+ rm -f "${RSYSLOG_DYNNAME}.HOSTNAME"
+ echo HOSTNAME is: $RS_HOSTNAME
+}
+
+
+# begin a new testconfig
+# 2018-09-07: Incremented inputs.timeout.shutdown to 60000 because kafka tests may not be
+# finished under stress otherwise
+# $1 is the instance id, if given
+generate_conf() {
+ if [ "$RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT" == "" ]; then
+ RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT="10000"
+ fi
+ if [ "$RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT" == "" ]; then
+ RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT="60000"
+ fi
+ if [ "$RSTB_ACTION_DEFAULT_Q_TO_SHUTDOWN" == "" ]; then
+ RSTB_ACTION_DEFAULT_Q_TO_SHUTDOWN="20000"
+ fi
+ if [ "$RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE" == "" ]; then
+ RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE="20000"
+ fi
+ export TCPFLOOD_PORT="$(get_free_port)"
+ if [ "$1" == "" ]; then
+ export TESTCONF_NM="${RSYSLOG_DYNNAME}_" # this basename is also used by instance 2!
+ export RSYSLOG_OUT_LOG="${RSYSLOG_DYNNAME}.out.log"
+ export RSYSLOG2_OUT_LOG="${RSYSLOG_DYNNAME}_2.out.log"
+ export RSYSLOG_PIDBASE="${RSYSLOG_DYNNAME}:" # also used by instance 2!
+ mkdir $RSYSLOG_DYNNAME.spool
+ fi
+ echo 'module(load="../plugins/imdiag/.libs/imdiag")
+global(inputs.timeout.shutdown="'$RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT'"
+ default.action.queue.timeoutshutdown="'$RSTB_ACTION_DEFAULT_Q_TO_SHUTDOWN'"
+ default.action.queue.timeoutEnqueue="'$RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE'")
+# use legacy-style for the following settings so that we can override if needed
+$MainmsgQueueTimeoutEnqueue 20000
+$MainmsgQueueTimeoutShutdown '$RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT'
+$IMDiagListenPortFileName '$RSYSLOG_DYNNAME.imdiag$1.port'
+$IMDiagServerRun 0
+$IMDiagAbortTimeout '$TB_TEST_MAX_RUNTIME'
+
+:syslogtag, contains, "rsyslogd" ./'${RSYSLOG_DYNNAME}$1'.started
+###### end of testbench instrumentation part, test conf follows:' > ${TESTCONF_NM}$1.conf
+}
+
+# add more data to config file. Note: generate_conf must have been called
+# $1 is config fragment, $2 the instance id, if given
+add_conf() {
+ printf '%s' "$1" >> ${TESTCONF_NM}$2.conf
+}
+
+
+rst_msleep() {
+ $TESTTOOL_DIR/msleep $1
+}
+
+
+# compare file to expected exact content
+# $1 is file to compare, default $RSYSLOG_OUT_LOG
+cmp_exact() {
+ filename=${1:-"$RSYSLOG_OUT_LOG"}
+ if [ "$filename" == "" ]; then
+ printf 'Testbench ERROR, cmp_exact() does not have a filename at ALL!\n'
+ error_exit 100
+ fi
+ if [ "$EXPECTED" == "" ]; then
+ printf 'Testbench ERROR, cmp_exact() needs to have env var EXPECTED set!\n'
+ error_exit 100
+ fi
+ printf '%s\n' "$EXPECTED" | cmp - "$filename"
+ if [ $? -ne 0 ]; then
+ printf 'invalid response generated\n'
+ printf '################# %s is:\n' "$filename"
+ cat -n $filename
+ printf '################# EXPECTED was:\n'
+ cat -n <<< "$EXPECTED"
+ printf '\n#################### diff is:\n'
+ diff - "$filename" <<< "$EXPECTED"
+ error_exit 1
+ fi;
+}
+
+# code common to all startup...() functions
+startup_common() {
+ instance=
+ if [ "$1" == "2" ]; then
+ CONF_FILE="${TESTCONF_NM}2.conf"
+ instance=2
+ elif [ "$1" == "" ] || [ "$1" == "1" ]; then
+ CONF_FILE="${TESTCONF_NM}.conf"
+ else
+ CONF_FILE="$srcdir/testsuites/$1"
+ instance=$2
+ fi
+ # we need to remove the imdiag port file as there are some
+ # tests that start multiple times. These may get the old port
+ # number if the file still exists AND timing is bad so that
+ # imdiag does not generate the port file quickly enough on
+ # startup.
+ rm -f $RSYSLOG_DYNNAME.imdiag$instance.port
+ if [ ! -f $CONF_FILE ]; then
+ echo "ERROR: config file '$CONF_FILE' not found!"
+ error_exit 1
+ fi
+ echo config $CONF_FILE is:
+ cat -n $CONF_FILE
+}
+
+# wait for appearance of a specific pid file, given as $1
+wait_startup_pid() {
+ if [ "$1" == "" ]; then
+ echo "FAIL: testbench bug: wait_startup_called without \$1"
+ error_exit 100
+ fi
+ while test ! -f $1; do
+ $TESTTOOL_DIR/msleep 100 # wait 100 milliseconds
+ if [ $(date +%s) -gt $(( TB_STARTTEST + TB_TEST_MAX_RUNTIME )) ]; then
+ printf '%s ABORT! Timeout waiting on startup (pid file %s)\n' "$(tb_timestamp)" "$1"
+ ls -l "$1"
+ ps -fp $($SUDO cat "$1")
+ error_exit 1
+ fi
+ done
+ printf '%s %s found, pid %s\n' "$(tb_timestamp)" "$1" "$(cat $1)"
+}
+
+# special version of wait_startup_pid() for rsyslog startup
+wait_rsyslog_startup_pid() {
+ wait_startup_pid $RSYSLOG_PIDBASE$1.pid
+}
+
+# wait for startup of an arbitrary process
+# $1 - pid file name
+# $2 - startup file name (optional, only checked if given)
+wait_process_startup() {
+ wait_startup_pid $1.pid
+ i=0
+ if [ "$2" != "" ]; then
+ while test ! -f "$2"; do
+ $TESTTOOL_DIR/msleep 100 # wait 100 milliseconds
+ ps -p $(cat $1.pid) &> /dev/null
+ if [ $? -ne 0 ]
+ then
+ echo "ABORT! pid in $1 no longer active during startup!"
+ error_exit 1
+ fi
+ (( i++ ))
+ if [ $(date +%s) -gt $(( TB_STARTTEST + TB_TEST_MAX_RUNTIME )) ]; then
+ printf '%s ABORT! Timeout waiting on file %s\n' "$(tb_timestamp)" "$2"
+ error_exit 1
+ fi
+ done
+ printf '%s %s seen, associated pid %s\n' "$(tb_timestamp)" "$2" "$(cat $1)"
+ fi
+}
+
+
+# wait for the pid in $1 to terminate, abort on timeout
+wait_pid_termination() {
+ out_pid="$1"
+ if [[ "$out_pid" == "" ]]; then
+ printf 'TESTBENCH error: pidfile name not specified in wait_pid_termination\n'
+ error_exit 100
+ fi
+ terminated=0
+ while [[ $terminated -eq 0 ]]; do
+ ps -p $out_pid &> /dev/null
+ if [[ $? != 0 ]]; then
+ terminated=1
+ fi
+ $TESTTOOL_DIR/msleep 100
+ if [ $(date +%s) -gt $(( TB_STARTTEST + TB_TEST_MAX_RUNTIME )) ]; then
+ printf '%s ABORT! Timeout waiting on shutdown (pid %s)\n' "$(tb_timestamp)" $out_pid
+ ps -fp $out_pid
+ printf 'Instance is possibly still running and may need manual cleanup.\n'
+ error_exit 1
+ fi
+ done
+ unset terminated
+ unset out_pid
+}
+
+# wait for file $1 to exist AND be non-empty
+# $1 : file to wait for
+# $2 (optional): error message to show if timeout occurs
+wait_file_exists() {
+ echo waiting for file $1
+ i=0
+ while true; do
+ if [ -f $1 ] && [ "$(cat $1 2> /dev/null)" != "" ]; then
+ break
+ fi
+ $TESTTOOL_DIR/msleep 100 # wait 100 milliseconds
+ ((i++))
+ if test $i -gt $TB_TIMEOUT_STARTSTOP; then
+ echo "ABORT! Timeout waiting for file $1"
+ ls -l $1
+ if [ "$2" != "" ]; then
+ echo "$2"
+ fi
+ error_exit 1
+ fi
+ done
+}
+
+# kafka special wait function: we wait for the output file in order
+# to ensure Kafka/Zookeeper is actually ready to go. This is NOT
+# a generic check function and must only used with those kafka tests
+# that actually need it.
+kafka_wait_group_coordinator() {
+echo We are waiting for kafka/zookeeper being ready to deliver messages
+wait_file_exists $RSYSLOG_OUT_LOG "
+
+Non-existence of $RSYSLOG_OUT_LOG can be caused
+by a problem inside zookeeper. If debug output in the receiver is enabled, one
+may see this message:
+
+\"GroupCoordinator response error: Broker: Group coordinator not available\"
+
+In this case you may want to do a web search and/or have a look at
+ https://github.com/edenhill/librdkafka/issues/799
+
+The question, of course, is if there is nevertheless a problem in imkafka.
+Usually, the wait we do inside the testbench is sufficient to handle all
+Zookeeper/Kafka startup. So if the issue reoccurs, it is suggested to enable
+debug output in the receiver and check for actual problems.
+"
+}
+
+# check if kafka itself failed. $1 is the message file name.
+kafka_check_broken_broker() {
+ failed=0
+ if grep "Broker transport failure" < "$1" ; then
+ failed=1
+ fi
+ if grep "broker connections are down" < "$1" ; then
+ failed=1
+ fi
+ if [ $failed -eq 1 ]; then
+ printf '\n\nenvironment-induced test error - kafka broker failed - skipping test\n'
+ printf 'content of %s:\n' "$1"
+ cat -n "$1"
+ error_exit 177
+ fi
+}
+
+# inject messages via kafkacat tool (for imkafka tests)
+# $1 == "--wait" means wait for rsyslog to receive TESTMESSAGES lines in RSYSLOG_OUT_LOG
+# $TESTMESSAGES contains number of messages to inject
+# $RANDTOPIC contains topic to produce to
+injectmsg_kafkacat() {
+ if [ "$1" == "--wait" ]; then
+ wait="YES"
+ shift
+ fi
+ if [ "$TESTMESSAGES" == "" ]; then
+ printf 'TESTBENCH ERROR: TESTMESSAGES env var not set!\n'
+ error_exit 1
+ fi
+ MAXATONCE=25000 # how many msgs should kafkacat send? - hint: current version errs out above ~70000
+ i=1
+ while (( i<=TESTMESSAGES )); do
+ currmsgs=0
+ while ((i <= $TESTMESSAGES && currmsgs != MAXATONCE)); do
+ printf ' msgnum:%8.8d\n' $i;
+ i=$((i + 1))
+ currmsgs=$((currmsgs+1))
+ done > "$RSYSLOG_DYNNAME.kafkacat.in"
+ set -e
+ kafkacat -P -b localhost:29092 -t $RANDTOPIC <"$RSYSLOG_DYNNAME.kafkacat.in" 2>&1 | tee >$RSYSLOG_DYNNAME.kafkacat.log
+ set +e
+ printf 'kafkacat injected %d msgs so far\n' $((i - 1))
+ kafka_check_broken_broker $RSYSLOG_DYNNAME.kafkacat.log
+ check_not_present "ERROR" $RSYSLOG_DYNNAME.kafkacat.log
+ cat $RSYSLOG_DYNNAME.kafkacat.log
+ done
+
+ if [ "$wait" == "YES" ]; then
+ wait_seq_check "$@"
+ fi
+}
+
+
+# wait for rsyslogd startup ($1 is the instance)
+wait_startup() {
+ wait_rsyslog_startup_pid $1
+ while test ! -f ${RSYSLOG_DYNNAME}$1.started; do
+ $TESTTOOL_DIR/msleep 100 # wait 100 milliseconds
+ ps -p $(cat $RSYSLOG_PIDBASE$1.pid) &> /dev/null
+ if [ $? -ne 0 ]
+ then
+ echo "ABORT! rsyslog pid no longer active during startup!"
+ error_exit 1 stacktrace
+ fi
+ if [ $(date +%s) -gt $(( TB_STARTTEST + TB_TEST_MAX_RUNTIME )) ]; then
+ printf '%s ABORT! Timeout waiting startup file %s\n' "$(tb_timestamp)" "${RSYSLOG_DYNNAME}.started"
+ error_exit 1
+ fi
+ done
+ echo "$(tb_timestamp) rsyslogd$1 startup msg seen, pid " $(cat $RSYSLOG_PIDBASE$1.pid)
+ wait_file_exists $RSYSLOG_DYNNAME.imdiag$1.port
+ eval export IMDIAG_PORT$1=$(cat $RSYSLOG_DYNNAME.imdiag$1.port)
+ eval PORT='$IMDIAG_PORT'$1
+ echo "imdiag$1 port: $PORT"
+ if [ "$PORT" == "" ]; then
+ echo "TESTBENCH ERROR: imdiag port not found!"
+ ls -l $RSYSLOG_DYNNAME*
+ exit 100
+ fi
+}
+
+# reassign ports after rsyslog startup; must be called from all
+# functions that startup rsyslog
+reassign_ports() {
+ if grep -q 'listenPortFileName="'$RSYSLOG_DYNNAME'\.tcpflood_port"' $CONF_FILE; then
+ assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+ fi
+ if grep -q '$InputTCPServerListenPortFile.*\.tcpflood_port' $CONF_FILE; then
+ assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+ fi
+}
+
+# start rsyslogd with default params. $1 is the config file name to use
+# returns only after successful startup, $2 is the instance (blank or 2!)
+# RS_REDIR maybe set to redirect rsyslog output
+# env var RSTB_DAEMONIZE" == "YES" means rsyslogd shall daemonize itself;
+# any other value or unset means it does not do that.
+startup() {
+ if [ "$USE_VALGRIND" == "YES" ]; then
+ startup_vg "$1" "$2"
+ return
+ elif [ "$USE_VALGRIND" == "YES-NOLEAK" ]; then
+ startup_vg_noleak "$1" "$2"
+ return
+ fi
+ startup_common "$1" "$2"
+ if [ "$RSTB_DAEMONIZE" == "YES" ]; then
+ n_option=""
+ else
+ n_option="-n"
+ fi
+ eval LD_PRELOAD=$RSYSLOG_PRELOAD $valgrind ../tools/rsyslogd -C $n_option -i$RSYSLOG_PIDBASE$instance.pid -M../runtime/.libs:../.libs -f$CONF_FILE $RS_REDIR &
+ wait_startup $instance
+ reassign_ports
+}
+
+
+# assign TCPFLOOD_PORT from port file
+# $1 - port file
+assign_tcpflood_port() {
+ wait_file_exists "$1"
+ export TCPFLOOD_PORT=$(cat "$1")
+ echo "TCPFLOOD_PORT now: $TCPFLOOD_PORT"
+ if [ "$TCPFLOOD_PORT" == "" ]; then
+ echo "TESTBENCH ERROR: TCPFLOOD_PORT not found!"
+ ls -l $RSYSLOG_DYNNAME*
+ exit 100
+ fi
+}
+
+
+# assign TCPFLOOD_PORT2 from port file
+# $1 - port file
+assign_tcpflood_port2() {
+ wait_file_exists "$1"
+ export TCPFLOOD_PORT2=$(cat "$1")
+ echo "TCPFLOOD_PORT2 now: $TCPFLOOD_PORT2"
+ if [ "$TCPFLOOD_PORT2" == "" ]; then
+ echo "TESTBENCH ERROR: TCPFLOOD_PORT2 not found!"
+ ls -l $RSYSLOG_DYNNAME*
+ exit 100
+ fi
+}
+# assign RS_PORT from port file - this is meant as generic way to
+# obtain additional port variables
+# $1 - port file
+assign_rs_port() {
+ wait_file_exists "$1"
+ export RS_PORT=$(cat "$1")
+ echo "RS_PORT now: $RS_PORT"
+ if [ "$RS_PORT" == "" ]; then
+ echo "TESTBENCH ERROR: RS_PORT not found!"
+ ls -l $RSYSLOG_DYNNAME*
+ exit 100
+ fi
+}
+
+# wait for a file to exist, then export it's content to env var
+# intended to be used for very small files, e.g. listenPort files
+# $1 - env var name
+# $2 - port file
+assign_file_content() {
+ wait_file_exists "$2"
+ content=$(cat "$2")
+ if [ "$content" == "" ]; then
+ echo "TESTBENCH ERROR: get_file content had empty file $2"
+ ls -l $RSYSLOG_DYNNAME*
+ exit 100
+ fi
+ eval export $1="$content"
+ printf 'exported: %s=%s\n' $1 "$content"
+}
+
+# same as startup_vg, BUT we do NOT wait on the startup message!
+startup_vg_waitpid_only() {
+ startup_common "$1" "$2"
+ if [ "$RS_TESTBENCH_LEAK_CHECK" == "" ]; then
+ RS_TESTBENCH_LEAK_CHECK=full
+ fi
+ # add --keep-debuginfo=yes for hard to find cases; this cannot be used generally,
+ # because it is only supported by newer versions of valgrind (else CI will fail
+ # on older platforms).
+ LD_PRELOAD=$RSYSLOG_PRELOAD valgrind $RS_TEST_VALGRIND_EXTRA_OPTS $RS_TESTBENCH_VALGRIND_EXTRA_OPTS --suppressions=$srcdir/known_issues.supp ${EXTRA_VALGRIND_SUPPRESSIONS:-} --gen-suppressions=all --log-fd=1 --error-exitcode=10 --malloc-fill=ff --free-fill=fe --leak-check=$RS_TESTBENCH_LEAK_CHECK ../tools/rsyslogd -C -n -i$RSYSLOG_PIDBASE$instance.pid -M../runtime/.libs:../.libs -f$CONF_FILE &
+ wait_rsyslog_startup_pid $1
+}
+
+# start rsyslogd with default params under valgrind control. $1 is the config file name to use
+# returns only after successful startup, $2 is the instance (blank or 2!)
+startup_vg() {
+ startup_vg_waitpid_only $1 $2
+ wait_startup $instance
+ reassign_ports
+}
+
+# same as startup-vg, except that --leak-check is set to "none". This
+# is meant to be used in cases where we have to deal with libraries (and such
+# that) we don't can influence and where we cannot provide suppressions as
+# they are platform-dependent. In that case, we can't test for leak checks
+# (obviously), but we can check for access violations, what still is useful.
+startup_vg_noleak() {
+ RS_TESTBENCH_LEAK_CHECK=no
+ startup_vg "$@"
+}
+
+# same as startup-vgthread, BUT we do NOT wait on the startup message!
+startup_vgthread_waitpid_only() {
+ startup_common "$1" "$2"
+ valgrind --tool=helgrind $RS_TEST_VALGRIND_EXTRA_OPTS $RS_TESTBENCH_VALGRIND_EXTRA_OPTS --log-fd=1 --error-exitcode=10 --suppressions=$srcdir/linux_localtime_r.supp --suppressions=$srcdir/known_issues.supp ${EXTRA_VALGRIND_SUPPRESSIONS:-} --suppressions=$srcdir/CI/gcov.supp --gen-suppressions=all ../tools/rsyslogd -C -n -i$RSYSLOG_PIDBASE$2.pid -M../runtime/.libs:../.libs -f$CONF_FILE &
+ wait_rsyslog_startup_pid $2
+}
+
+# start rsyslogd with default params under valgrind thread debugger control.
+# $1 is the config file name to use, $2 is the instance (blank or 2!)
+# returns only after successful startup
+startup_vgthread() {
+ startup_vgthread_waitpid_only $1 $2
+ wait_startup $2
+ reassign_ports
+}
+
+
+# inject messages via our inject interface (imdiag)
+# $1 is start message number, env var NUMMESSAGES is number of messages to inject
+injectmsg() {
+ if [ "$3" != "" ] ; then
+ printf 'error: injectmsg only has two arguments, extra arg is %s\n' "$3"
+ fi
+ msgs=${2:-$NUMMESSAGES}
+ echo injecting $msgs messages
+ echo injectmsg "${1:-0}" "$msgs" | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+}
+
+# inject messages in INSTANCE 2 via our inject interface (imdiag)
+injectmsg2() {
+ msgs=${2:-$NUMMESSAGES}
+ echo injecting $msgs messages into instance 2
+ echo injectmsg "${1:-0}" "$msgs" $3 $4 | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT2 || error_exit $?
+ # TODO: some return state checking? (does it really make sense here?)
+}
+
+# inject literal payload via our inject interface (imdiag)
+injectmsg_literal() {
+ printf 'injecting msg payload: %s\n' "$1"
+ sed -e 's/^/injectmsg literal /g' <<< "$1" | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+}
+
+# inject literal payload via our inject interface (imdiag)
+injectmsg_file() {
+ printf 'injecting msg payload: %s\n' "$1"
+ sed -e 's/^/injectmsg literal /g' < "$1" | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+}
+
+
+# show the current main queue size. $1 is the instance.
+get_mainqueuesize() {
+ if [ "$1" == "2" ]; then
+ echo getmainmsgqueuesize | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT2 || error_exit $?
+ else
+ echo getmainmsgqueuesize | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+ fi
+}
+
+# get pid of rsyslog instance $1
+getpid() {
+ printf '%s' "$(cat $RSYSLOG_PIDBASE$1.pid)"
+}
+
+# grep for (partial) content. $1 is the content to check for, $2 the file to check
+# option --check-only just returns success/fail but does not terminate on fail
+# this is meant for checking during queue shutdown processing.
+# option --regex is understood, in which case $1 is a regex
+content_check() {
+ if [ "$1" == "--check-only" ]; then
+ check_only="yes"
+ shift
+ else
+ check_only="no"
+ fi
+ if [ "$1" == "--regex" ]; then
+ grep_opt=
+ shift
+ else
+ grep_opt=-F
+ fi
+ if [ "$1" == "--output-results" ]; then
+ output_results="yes"
+ shift
+ else
+ output_results="no"
+ fi
+ file=${2:-$RSYSLOG_OUT_LOG}
+ if ! grep -q $grep_opt -- "$1" < "${file}"; then
+ if [ "$check_only" == "yes" ]; then
+ printf 'content_check did not yet succeed\n'
+ return 1
+ fi
+ printf '\n============================================================\n'
+ printf 'FILE "%s" content:\n' "$file"
+ cat -n ${file}
+ printf 'FAIL: content_check failed to find "%s"\n' "$1"
+ error_exit 1
+ else
+ if [ "$output_results" == "yes" ]; then
+ # Output GREP results
+ echo "SUCCESS: content_check found results for '$1'\n"
+ grep "$1" "${file}"
+ fi
+ fi
+ if [ "$check_only" == "yes" ]; then
+ return 0
+ fi
+}
+
+
+# grep for (partial) content. this checks the count of the content
+# $1 is the content to check for
+# $2 required count
+# $3 the file to check (if default not used)
+# option --regex is understood, in which case $1 is a regex
+content_count_check() {
+ if [ "$1" == "--regex" ]; then
+ grep_opt=
+ shift
+ else
+ grep_opt=-F
+ fi
+ file=${3:-$RSYSLOG_OUT_LOG}
+ count=$(grep -c $grep_opt -- "$1" <${RSYSLOG_OUT_LOG})
+ if [ ${count:=0} -ne "$2" ]; then
+ grep -c -F -- "$1" <${RSYSLOG_OUT_LOG}
+ printf '\n============================================================\n'
+ printf 'FILE "%s" content:\n' "$file"
+ cat -n ${file}
+ printf 'FAIL: content count required %d but was %d\n' "$2" $count
+ printf 'FAIL: content_check failed to find "%s"\n' "$1"
+ error_exit 1
+ fi
+}
+
+
+
+# $1 - content to check for
+# $2 - number of times content must appear
+# $3 - timeout (default: 1)
+content_check_with_count() {
+ timeoutend=${3:-1}
+ timecounter=0
+ while [ $timecounter -lt $timeoutend ]; do
+ (( timecounter=timecounter+1 ))
+ count=0
+ if [ -f "${RSYSLOG_OUT_LOG}" ]; then
+ count=$(grep -c -F -- "$1" <${RSYSLOG_OUT_LOG})
+ fi
+ if [ ${count:=0} -eq $2 ]; then
+ echo content_check_with_count SUCCESS, \"$1\" occurred $2 times
+ break
+ else
+ if [ "$timecounter" == "$timeoutend" ]; then
+ shutdown_when_empty ""
+ wait_shutdown ""
+
+ echo "$(tb_timestamp)" content_check_with_count failed, expected \"$1\" to occur $2 times, but found it "$count" times
+ echo file $RSYSLOG_OUT_LOG content is:
+ if [ $(wc -l < "$RSYSLOG_OUT_LOG") -gt 10000 ]; then
+ printf 'truncation, we have %d lines, which is way too much\n' \
+ $(wc -l < "$RSYSLOG_OUT_LOG")
+ printf 'showing first and last 5000 lines\n'
+ head -n 5000 < "$RSYSLOG_OUT_LOG"
+ print '\n ... CUT ..................................................\n\n'
+ tail -n 5000 < "$RSYSLOG_OUT_LOG"
+ else
+ cat -n "$RSYSLOG_OUT_LOG"
+ fi
+ error_exit 1
+ else
+ printf '%s content_check_with_count, try %d have %d, wait for %d, search for: "%s"\n' \
+ "$(tb_timestamp)" "$timecounter" "$count" "$2" "$1"
+ $TESTTOOL_DIR/msleep 1000
+ fi
+ fi
+ printf '%s **** content_check_with_count DEBUG (timeout %s, need %s lines):\n' "$(tb_timestamp)" "$3" "$2" # rger: REMOVE ME when problems are fixed
+ if [ -f "${RSYSLOG_OUT_LOG}" ]; then cat -n "$RSYSLOG_OUT_LOG"; fi
+ done
+}
+
+
+custom_content_check() {
+ grep -qF -- "$1" < $2
+ if [ "$?" -ne "0" ]; then
+ echo FAIL: custom_content_check failed to find "'$1'" inside "'$2'"
+ echo "file contents:"
+ cat -n $2
+ error_exit 1
+ fi
+}
+
+# check that given content $1 is not present in file $2 (default: RSYSLOG_OUT_LOG)
+# regular expressions may be used
+check_not_present() {
+ if [ "$2" == "" ]; then
+ file=$RSYSLOG_OUT_LOG
+ else
+ file="$2"
+ fi
+ grep -q -- "$1" < "$file"
+ if [ "$?" -eq "0" ]; then
+ echo FAIL: check_not present found
+ echo $1
+ echo inside file $file of $(wc -l < $file) lines
+ echo samples:
+ cat -n "$file" | grep -- "$1" | head -10
+ error_exit 1
+ fi
+}
+
+
+# check if mainqueue spool files exist, if not abort (we just check .qi).
+check_mainq_spool() {
+ printf 'There must exist some files now:\n'
+ ls -l $RSYSLOG_DYNNAME.spool
+ printf '.qi file:\n'
+ cat $RSYSLOG_DYNNAME.spool/mainq.qi
+ if [ ! -f $RSYSLOG_DYNNAME.spool/mainq.qi ]; then
+ printf 'error: mainq.qi does not exist where expected to do so!\n'
+ error_exit 1
+ fi
+}
+# check that no spool file exists. Abort if they do.
+# This situation must exist after a successful termination of rsyslog
+# where the disk queue has properly been drained and shut down.
+check_spool_empty() {
+ if [ "$(ls $RSYSLOG_DYNNAME.spool/* 2> /dev/null)" != "" ]; then
+ printf 'error: spool files exists where they are not permitted to do so:\n'
+ ls -l $RSYSLOG_DYNNAME.spool/*
+ error_exit 1
+ fi
+}
+
+# general helper for imjournal tests: check that we got hold of the
+# injected test message. This is pretty lengthy as the journal has played
+# "a bit" with us and also seems to sometimes have a heavy latency in
+# forwarding messages. So let's centralize the check code.
+#
+# $TESTMSG must contain the test message
+check_journal_testmsg_received() {
+ printf 'checking that journal indeed contains test message - may take a short while...\n'
+ # search reverse, gets us to our message (much) faster .... if it is there...
+ journalctl -a -r | grep -qF "$TESTMSG"
+ if [ $? -ne 0 ]; then
+ print 'SKIP: cannot read journal - our testmessage not found via journalctl\n'
+ exit 77
+ fi
+ printf 'journal contains test message\n'
+
+ echo "INFO: $(wc -l < $RSYSLOG_OUT_LOG) lines in $RSYSLOG_OUT_LOG"
+
+ grep -qF "$TESTMSG" < $RSYSLOG_OUT_LOG
+ if [ $? -ne 0 ]; then
+ echo "FAIL: $RSYSLOG_OUT_LOG content (tail -n200):"
+ tail -n200 $RSYSLOG_OUT_LOG
+ echo "======="
+ echo "searching journal for testbench messages:"
+ journalctl -a | grep -qF "TestBenCH-RSYSLog imjournal"
+ echo "======="
+ echo "NOTE: showing only last 200 lines, may be insufficient on busy systems!"
+ echo "last entries from journal:"
+ journalctl -an 200
+ echo "======="
+ echo "NOTE: showing only last 200 lines, may be insufficient on busy systems!"
+ echo "However, the test check all of the journal, we are just limiting the output"
+ echo "to 200 lines to not spam CI systems too much."
+ echo "======="
+ echo "FAIL: imjournal test message could not be found!"
+ echo "Expected message content was:"
+ echo "$TESTMSG"
+ error_exit 1
+ fi;
+}
+
+# checks that among the open files found in /proc/<PID>/fd/*
+# there is or is not, depending on the calling mode,
+# a link with the specified suffix in the target name
+check_fd_for_pid() {
+ local pid="$1" mode="$2" suffix="$3" target seen
+ seen="false"
+ for fd in $(echo /proc/$pid/fd/*); do
+ target="$(readlink -m "$fd")"
+ if [[ "$target" != *$RSYSLOG_DYNNAME* ]]; then
+ continue
+ fi
+ if ((i % 10 == 0)); then
+ echo "INFO: check target='$target'"
+ fi
+ if [[ "$target" == *$suffix ]]; then
+ seen="true"
+ if [[ "$mode" == "exists" ]]; then
+ echo "PASS: check fd for pid=$pid mode='$mode' suffix='$suffix'"
+ return 0
+ fi
+ fi
+ done
+ if [[ "$seen" == "false" ]] && [[ "$mode" == "absent" ]]; then
+ echo "PASS: check fd for pid=$pid mode='$mode' suffix='$suffix'"
+ return 0
+ fi
+ echo "FAIL: check fd for pid=$pid mode='$mode' suffix='$suffix'"
+ if [[ "$mode" != "ignore" ]]; then
+ return 1
+ fi
+ return 0
+}
+
+# wait for main message queue to be empty. $1 is the instance.
+# we run in a loop to ensure rsyslog is *really* finished when a
+# function for the "finished predicate" is defined. This is done
+# by setting env var QUEUE_EMPTY_CHECK_FUNC to the bash
+# function name.
+wait_queueempty() {
+ while [ $(date +%s) -le $(( TB_STARTTEST + TB_TEST_MAX_RUNTIME )) ]; do
+ if [ "$1" == "2" ]; then
+ echo WaitMainQueueEmpty | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT2 || error_exit $?
+ else
+ echo WaitMainQueueEmpty | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+ fi
+ if [ "$QUEUE_EMPTY_CHECK_FUNC" == "" ]; then
+ return
+ else
+ if $QUEUE_EMPTY_CHECK_FUNC ; then
+ return
+ fi
+ fi
+ done
+ error_exit $TB_ERR_TIMEOUT
+}
+
+
+# shut rsyslogd down when main queue is empty. $1 is the instance.
+shutdown_when_empty() {
+ echo Shutting down instance ${1:-1}
+ wait_queueempty $1
+ if [ "$RSYSLOG_PIDBASE" == "" ]; then
+ echo "RSYSLOG_PIDBASE is EMPTY! - bug in test? (instance $1)"
+ error_exit 1
+ fi
+ cp $RSYSLOG_PIDBASE$1.pid $RSYSLOG_PIDBASE$1.pid.save
+ $TESTTOOL_DIR/msleep 500 # wait a bit (think about slow testbench machines!)
+ kill $(cat $RSYSLOG_PIDBASE$1.pid) # note: we do not wait for the actual termination!
+}
+
+# shut rsyslogd down without emptying the queue. $2 is the instance.
+shutdown_immediate() {
+ pidfile=$RSYSLOG_PIDBASE${1:-}.pid
+ cp $pidfile $pidfile.save
+ kill $(cat $pidfile)
+}
+
+
+# actually, we wait for rsyslog.pid to be deleted.
+# $1 is the instance
+wait_shutdown() {
+ if [ "$USE_VALGRIND" == "YES" ] || [ "$USE_VALGRIND" == "YES-NOLEAK" ]; then
+ wait_shutdown_vg "$1"
+ return
+ fi
+ out_pid=$(cat $RSYSLOG_PIDBASE$1.pid.save)
+ printf '%s wait on shutdown of %s\n' "$(tb_timestamp)" "$out_pid"
+ if [[ "$out_pid" == "" ]]
+ then
+ terminated=1
+ else
+ terminated=0
+ fi
+ while [[ $terminated -eq 0 ]]; do
+ ps -p $out_pid &> /dev/null
+ if [[ $? != 0 ]]; then
+ terminated=1
+ fi
+ $TESTTOOL_DIR/msleep 100 # wait 100 milliseconds
+ if [ $(date +%s) -gt $(( TB_STARTTEST + TB_TEST_MAX_RUNTIME )) ]; then
+ printf '%s wait_shutdown ABORT! Timeout waiting on shutdown (pid %s)\n' "$(tb_timestamp)" $out_pid
+ ps -fp $out_pid
+ echo "Instance is possibly still running and may need"
+ echo "manual cleanup."
+ echo "TRYING TO capture status via gdb from hanging process"
+ $SUDO gdb ../tools/rsyslogd <<< "attach $out_pid
+set pagination off
+inf thr
+thread apply all bt
+quit"
+ echo "trying to kill -9 process"
+ kill -9 $out_pid
+ error_exit 1
+ fi
+ done
+ unset terminated
+ unset out_pid
+ if [ "$(ls core.* 2>/dev/null)" != "" ]; then
+ printf 'ABORT! core file exists (maybe from a parallel run!)\n'
+ pwd
+ ls -l core.*
+ error_exit 1
+ fi
+}
+
+
+# wait for HUP to complete. $1 is the instance
+# note: there is a slight chance HUP was not completed. This can happen if it takes
+# the system very long (> 500ms) to receive the HUP and set the internal flag
+# variable. aka "very very low probability".
+await_HUP_processed() {
+ if [ "$1" == "2" ]; then
+ echo AwaitHUPComplete | $TESTTOOL_DIR/diagtalker -pIMDIAG_PORT2 || error_exit $?
+ else
+ echo AwaitHUPComplete | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+ fi
+}
+
+
+# wait for all pending lookup table reloads to complete $1 is the instance.
+await_lookup_table_reload() {
+ if [ "$1" == "2" ]; then
+ echo AwaitLookupTableReload | $TESTTOOL_DIR/diagtalker -pIMDIAG_PORT2 || error_exit $?
+ else
+ echo AwaitLookupTableReload | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+ fi
+}
+
+# $1 filename, default $RSYSLOG_OUT_LOG
+# $2 expected nbr of lines, default $NUMMESSAGES
+# $3 timeout in seconds
+# options (need to be specified in THIS ORDER if multiple given):
+# --delay ms -- if given, delay to use between retries
+# --abort-on-oversize -- error_exit if more lines than expected are present
+# --count-function func -- function to call to obtain current count
+# this permits to override the default predicate and makes
+# the wait really universally usable.
+wait_file_lines() {
+ delay=200
+ if [ "$1" == "--delay" ]; then
+ delay="$2"
+ shift 2
+ fi
+ abort_oversize=NO
+ if [ "$1" == "--abort-on-oversize" ]; then
+ abort_oversize="YES"
+ shift
+ fi
+ count_function=
+ if [ "$1" == "--count-function" ]; then
+ count_function="$2"
+ shift 2
+ fi
+ interrupt_connection=NO
+ if [ "$1" == "--interrupt-connection" ]; then
+ interrupt_connection="YES"
+ interrupt_host="$2"
+ interrupt_port="$3"
+ interrupt_tick="$4"
+ shift 4
+ lastcurrent_time=0
+ fi
+
+ timeout=${3:-$TB_TEST_TIMEOUT}
+ timeoutbegin=$(date +%s)
+ timeoutend=$(( timeoutbegin + timeout ))
+ # TODO: change this to support odl mode, if needed: timeoutend=${3:-200}
+ file=${1:-$RSYSLOG_OUT_LOG}
+ waitlines=${2:-$NUMMESSAGES}
+
+ while true ; do
+ count=0
+ if [ "$count_function" == "" ]; then
+ if [ -f "$file" ]; then
+ if [ "$COUNT_FILE_IS_ZIPPED" == "yes" ]; then
+ issue_HUP ""
+ count=$(gunzip < "$file" | wc -l)
+ else
+ count=$(wc -l < "$file")
+ fi
+ fi
+ else
+ count=$($count_function)
+ fi
+ if [ ${count} -gt $waitlines ]; then
+ if [ $abort_oversize == "YES" ] && [ ${count} -gt $waitlines ]; then
+ printf 'FAIL: wait_file_lines, too many lines, expected %d, current %s, took %s seconds\n' \
+ $waitlines $count "$(( $(date +%s) - timeoutbegin ))"
+ error_exit 1
+ else
+ printf 'wait_file_lines success, target %d or more lines, have %d, took %d seconds\n' \
+ "$waitlines" $count "$(( $(date +%s) - timeoutbegin ))"
+ return
+ fi
+ fi
+ if [ ${count} -eq $waitlines ]; then
+ echo wait_file_lines success, have $waitlines lines, took $(( $(date +%s) - timeoutbegin )) seconds, file "$file"
+ break
+ else
+ if [ $(date +%s) -ge $timeoutend ]; then
+ echo wait_file_lines failed, expected $waitlines got $count after $timeoutend retries, took $(( $(date +%s) - timeoutbegin )) seconds
+ error_exit 1
+ else
+ echo $(date +%H:%M:%S) wait_file_lines waiting, expected $waitlines, current $count lines
+
+ current_time=$(date +%s)
+ if [ $interrupt_connection == "YES" ] && [ $current_time -gt $lastcurrent_time ] && [ $((current_time % $interrupt_tick)) -eq 0 ] && [ ${count} -gt 1 ]; then
+ # Interrupt Connection - requires root and linux kernel >= 4.9 in order to work!
+ echo wait_file_lines Interrupt Connection on ${interrupt_host}:${interrupt_port}
+ sudo ss -K dst ${interrupt_host} dport = ${interrupt_port}
+ fi
+ lastcurrent_time=$current_time
+
+ $TESTTOOL_DIR/msleep $delay
+ fi
+ fi
+ done
+}
+
+
+
+
+# wait until seq_check succeeds. This is used to synchronize various
+# testbench timing-related issues, most importantly rsyslog shutdown
+# all parameters are passed to seq_check
+wait_seq_check() {
+ timeoutend=$(( $(date +%s) + TB_TEST_TIMEOUT ))
+ if [ "$SEQ_CHECK_FILE" == "" ]; then
+ filename="$RSYSLOG_OUT_LOG"
+ else
+ filename="$SEQ_CHECK_FILE"
+ fi
+
+ while true ; do
+ if [ "$PRE_SEQ_CHECK_FUNC" != "" ]; then
+ $PRE_SEQ_CHECK_FUNC
+ fi
+ if [ "${filename##.*}" != "gz" ]; then
+ if [ -f "$filename" ]; then
+ count=$(wc -l < "$filename")
+ fi
+ fi
+ seq_check --check-only "$@" #&>/dev/null
+ ret=$?
+ if [ $ret == 0 ]; then
+ printf 'wait_seq_check success (%d lines)\n' "$count"
+ break
+ else
+ if [ $(date +%s) -ge $timeoutend ]; then
+ printf 'wait_seq_check failed, no success before timeout\n'
+ error_exit 1
+ else
+ printf 'wait_seq_check waiting (%d lines)\n' $count
+ $TESTTOOL_DIR/msleep 500
+ fi
+ fi
+ done
+ unset count
+}
+
+
+# wait until some content appears in the specified file.
+# This is used to synchronize various
+# testbench timing-related issues, most importantly rsyslog shutdown
+# all parameters are passed to seq_check
+# $1 - content to search for
+# $2 - file to check
+wait_content() {
+ file=${2:-$RSYSLOG_OUT_LOG}
+ timeoutend=$(( $(date +%s) + TB_TEST_TIMEOUT ))
+ count=0
+
+ while true ; do
+ if [ -f "$file" ]; then
+ count=$(wc -l < "$file")
+ if grep -q "$1" < "$file"; then
+ printf 'expected content found, continue test (%d lines)\n' "$count"
+ break
+ fi
+ fi
+ if [ $(date +%s) -ge $timeoutend ]; then
+ printf 'wait_content failed, no success before timeout (%d lines)\n' "$count"
+ printf 'searched content was:\n%s\n' "$1"
+ error_exit 1
+ else
+ printf 'wait_content still waiting... (%d lines)\n' "$count"
+ tail "$file"
+ $TESTTOOL_DIR/msleep 500
+ fi
+ done
+ unset count
+}
+
+
+assert_content_missing() {
+ grep -qF -- "$1" < ${RSYSLOG_OUT_LOG}
+ if [ "$?" -eq "0" ]; then
+ echo content-missing assertion failed, some line matched pattern "'$1'"
+ error_exit 1
+ fi
+}
+
+
+custom_assert_content_missing() {
+ grep -qF -- "$1" < $2
+ if [ "$?" -eq "0" ]; then
+ echo content-missing assertion failed, some line in "'$2'" matched pattern "'$1'"
+ cat -n "$2"
+ error_exit 1
+ fi
+}
+
+
+# shut rsyslogd down when main queue is empty. $1 is the instance.
+issue_HUP() {
+ if [ "$1" == "--sleep" ]; then
+ sleeptime="$2"
+ shift 2
+ else
+ sleeptime=1000
+ fi
+ kill -HUP $(cat $RSYSLOG_PIDBASE$1.pid)
+ printf 'HUP issued to pid %d - waiting for it to become processed\n' \
+ $(cat $RSYSLOG_PIDBASE$1.pid)
+ await_HUP_processed
+ #$TESTTOOL_DIR/msleep $sleeptime
+}
+
+
+# actually, we wait for rsyslog.pid to be deleted. $1 is the instance
+wait_shutdown_vg() {
+ wait $(cat $RSYSLOG_PIDBASE$1.pid)
+ export RSYSLOGD_EXIT=$?
+ echo rsyslogd run exited with $RSYSLOGD_EXIT
+
+ if [ "$(ls vgcore.* 2>/dev/null)" != "" ]; then
+ printf 'ABORT! core file exists:\n'
+ ls -l vgcore.*
+ error_exit 1
+ fi
+ if [ "$USE_VALGRIND" == "YES" ] || [ "$USE_VALGRIND" == "YES-NOLEAK" ]; then
+ check_exit_vg
+ fi
+}
+
+check_file_exists() {
+ if [ ! -f "$1" ]; then
+ printf 'FAIL: file "%s" must exist, but does not\n' "$1"
+ error_exit 1
+ fi
+}
+
+check_file_not_exists() {
+ if [ -f "$1" ]; then
+ printf 'FILE %s CONTENT:\n' "$1"
+ cat -n -- "$1"
+ printf 'FAIL: file "%s" must NOT exist, but does\n' "$1"
+ error_exit 1
+ fi
+}
+
+# check exit code for valgrind error
+check_exit_vg(){
+ if [ "$RSYSLOGD_EXIT" -eq "10" ]; then
+ printf 'valgrind run FAILED with exceptions - terminating\n'
+ error_exit 1
+ fi
+}
+
+
+# do cleanup during exit processing
+do_cleanup() {
+ if [ "$(type -t test_error_exit_handler)" == "function" ]; then
+ test_error_exit_handler
+ fi
+
+ if [ -f $RSYSLOG_PIDBASE.pid ]; then
+ printf 'rsyslog pid file still exists, trying to shutdown...\n'
+ shutdown_immediate ""
+ fi
+ if [ -f ${RSYSLOG_PIDBASE}1.pid ]; then
+ printf 'rsyslog pid file still exists, trying to shutdown...\n'
+ shutdown_immediate 1
+ fi
+ if [ -f ${RSYSLOG_PIDBASE}2.pid ]; then
+ printf 'rsyslog pid file still exists, trying to shutdown...\n'
+ shutdown_immediate 2
+ fi
+}
+
+
+# this is called if we had an error and need to abort. Here, we
+# try to gather as much information as possible. That's most important
+# for systems like Travis-CI where we cannot debug on the machine itself.
+# our $1 is the to-be-used exit code. if $2 is "stacktrace", call gdb.
+#
+# NOTE: if a function test_error_exit_handler is defined, error_exit will
+# call it immediately before termination. This may be used to cleanup
+# some things or emit additional diagnostic information.
+error_exit() {
+ if [ $1 -eq $TB_ERR_TIMEOUT ]; then
+ printf '%s Test %s exceeded max runtime of %d seconds\n' "$(tb_timestamp)" "$0" $TB_TEST_MAX_RUNTIME
+ fi
+ if [ "$(ls core* 2>/dev/null)" != "" ]; then
+ echo trying to obtain crash location info
+ echo note: this may not be the correct file, check it
+ CORE=$(ls core*)
+ echo "bt" >> gdb.in
+ echo "q" >> gdb.in
+ gdb ../tools/rsyslogd $CORE -batch -x gdb.in
+ CORE=
+ rm gdb.in
+ fi
+ if [[ "$2" == 'stacktrace' || ( ! -e IN_AUTO_DEBUG && "$USE_AUTO_DEBUG" == 'on' ) ]]; then
+ if [ "$(ls core* 2>/dev/null)" != "" ]; then
+ CORE=$(ls core*)
+ printf 'trying to analyze core "%s" for main rsyslogd binary\n' "$CORE"
+ printf 'note: this may not be the correct file, check it\n'
+ $SUDO gdb ../tools/rsyslogd "$CORE" -batch <<- EOF
+ bt
+ echo === THREAD INFO ===
+ info thread
+ echo === thread apply all bt full ===
+ thread apply all bt full
+ q
+ EOF
+ $SUDO gdb ./tcpflood "$CORE" -batch <<- EOF
+ bt
+ echo === THREAD INFO ===
+ info thread
+ echo === thread apply all bt full ===
+ thread apply all bt full
+ q
+ EOF
+ fi
+ fi
+ if [[ ! -e IN_AUTO_DEBUG && "$USE_AUTO_DEBUG" == 'on' ]]; then
+ touch IN_AUTO_DEBUG
+ # OK, we have the testname and can re-run under valgrind
+ echo re-running under valgrind control
+ current_test="./$(basename $0)" # this path is probably wrong -- theinric
+ $current_test
+ # wait a little bit so that valgrind can finish
+ $TESTTOOL_DIR/msleep 4000
+ # next let's try us to get a debug log
+ RSYSLOG_DEBUG_SAVE=$RSYSLOG_DEBUG
+ export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction"
+ $current_test
+ $TESTTOOL_DIR/msleep 4000
+ RSYSLOG_DEBUG=$RSYSLOG_DEBUG_SAVE
+ rm IN_AUTO_DEBUG
+ fi
+ # output listening ports as a temporary debug measure (2018-09-08 rgerhards), now disables, but not yet removed (2018-10-22)
+ #if [ $(uname) == "Linux" ]; then
+ # netstat -tlp
+ #else
+ # netstat
+ #fi
+
+ # Extended debug output for dependencies started by testbench
+ if [ "$EXTRA_EXITCHECK" == 'dumpkafkalogs' ] && [ "$TEST_OUTPUT" == "VERBOSE" ]; then
+ # Dump Zookeeper log
+ dump_zookeeper_serverlog
+ # Dump Kafka log
+ dump_kafka_serverlog
+ fi
+
+ # Extended Exit handling for kafka / zookeeper instances
+ kafka_exit_handling "false"
+
+ # Ensure redis instance is stopped
+ if [ -n "$REDIS_DYN_DIR" ]; then
+ stop_redis
+ fi
+
+ error_stats $1 # Report error to rsyslog testbench stats
+ do_cleanup
+
+ exitval=$1
+ if [ "$TEST_STATUS" == "unreliable" ] && [ "$1" -ne 100 ]; then
+ # TODO: log github issue
+ printf 'Test flagged as unreliable, exiting with SKIP. Original exit code was %d\n' "$1"
+ printf 'GitHub ISSUE: %s\n' "$TEST_GITHUB_ISSUE"
+ exitval=77
+ else
+ if [ "$1" -eq 177 ]; then
+ exitval=77
+ fi
+ fi
+ printf '%s FAIL: Test %s (took %s seconds)\n' "$(tb_timestamp)" "$0" "$(( $(date +%s) - TB_STARTTEST ))"
+ if [ $exitval -ne 77 ]; then
+ echo $0 > testbench_test_failed_rsyslog
+ fi
+ exit $exitval
+}
+
+
+# skip a test; do cleanup when we detect it is necessary
+skip_test(){
+ do_cleanup
+ exit 77
+}
+
+
+# Helper function to call rsyslog project test error script
+# $1 is the exit code
+error_stats() {
+ if [ "$RSYSLOG_STATSURL" == "" ]; then
+ printf 'not reporting failure as RSYSLOG_STATSURL is not set\n'
+ else
+ echo reporting failure to $RSYSLOG_STATSURL
+ testname=$($PYTHON $srcdir/urlencode.py "$RSYSLOG_TESTNAME")
+ testenv=$($PYTHON $srcdir/urlencode.py "${VCS_SLUG:-$PWD}")
+ testmachine=$($PYTHON $srcdir/urlencode.py "$HOSTNAME")
+ logurl=$($PYTHON $srcdir/urlencode.py "${CI_BUILD_URL:-}")
+ wget -nv -O/dev/null $RSYSLOG_STATSURL\?Testname=$testname\&Testenv=$testenv\&Testmachine=$testmachine\&exitcode=${1:-1}\&logurl=$logurl\&rndstr=jnxv8i34u78fg23
+ fi
+}
+
+# do the usual sequence check to see if everything was properly received.
+# $4... are just to have the ability to pass in more options...
+# add -v to chkseq if you need more verbose output
+# argument --check-only can be used to simply do a check without abort in fail case
+# env var SEQ_CHECK_FILE permits to override file name to check
+# env var SEQ_CHECK_OPTIONS provide the ability to add extra options for check program
+seq_check() {
+ if [ "$SEQ_CHECK_FILE" == "" ]; then
+ SEQ_CHECK_FILE="$RSYSLOG_OUT_LOG"
+ fi
+ if [ "$1" == "--check-only" ]; then
+ check_only="YES"
+ shift
+ else
+ check_only="NO"
+ fi
+ if [ "$1" == "" ]; then
+ if [ "$NUMMESSAGES" == "" ]; then
+ printf 'FAIL: seq_check called without parameters but NUMMESSAGES is unset!\n'
+ error_exit 100
+ fi
+ # use default parameters
+ startnum=0
+ endnum=$(( NUMMESSAGES - 1 ))
+ else
+ startnum=$1
+ endnum=$2
+ fi
+ if [ ! -f "$SEQ_CHECK_FILE" ]; then
+ if [ "$check_only" == "YES" ]; then
+ return 1
+ fi
+ printf 'FAIL: %s does not exist in seq_check!\n' "$SEQ_CHECK_FILE"
+ error_exit 1
+ fi
+ if [ "${SEQ_CHECK_FILE##*.}" == "gz" ]; then
+ gunzip -c "${SEQ_CHECK_FILE}" | $RS_SORTCMD $RS_SORT_NUMERIC_OPT | ./chkseq -s$startnum -e$endnum $3 $4 $5 $6 $7 $SEQ_CHECK_OPTIONS
+ elif [ "${SEQ_CHECK_FILE##*.}" == "zst" ]; then
+ ls -l "${SEQ_CHECK_FILE}"
+ unzstd < "${SEQ_CHECK_FILE}" | $RS_SORTCMD $RS_SORT_NUMERIC_OPT | ./chkseq -s$startnum -e$endnum $3 $4 $5 $6 $7 $SEQ_CHECK_OPTIONS
+ else
+ $RS_SORTCMD $RS_SORT_NUMERIC_OPT < "${SEQ_CHECK_FILE}" | ./chkseq -s$startnum -e$endnum $3 $4 $5 $6 $7 $SEQ_CHECK_OPTIONS
+ fi
+ ret=$?
+ if [ "$check_only" == "YES" ]; then
+ return $ret
+ fi
+ if [ $ret -ne 0 ]; then
+ if [ "${SEQ_CHECK_FILE##*.}" == "gz" ]; then
+ gunzip -c "${SEQ_CHECK_FILE}" | $RS_SORTCMD $RS_SORT_NUMERIC_OPT \
+ | ./chkseq -s$startnum -e$endnum $3 $4 $5 $6 $7 $SEQ_CHECK_OPTIONS \
+ > $RSYSLOG_DYNNAME.error.log
+ elif [ "${SEQ_CHECK_FILE##*.}" == "zst" ]; then
+ unzstd < "${SEQ_CHECK_FILE}" | $RS_SORTCMD $RS_SORT_NUMERIC_OPT \
+ | ./chkseq -s$startnum -e$endnum $3 $4 $5 $6 $7 $SEQ_CHECK_OPTIONS \
+ > $RSYSLOG_DYNNAME.error.log
+ else
+ $RS_SORTCMD $RS_SORT_NUMERIC_OPT < ${SEQ_CHECK_FILE} \
+ > $RSYSLOG_DYNNAME.error.log
+ fi
+ echo "sequence error detected in $SEQ_CHECK_FILE"
+ echo "number of lines in file: $(wc -l $SEQ_CHECK_FILE)"
+ echo "sorted data has been placed in error.log, first 10 lines are:"
+ cat -n "$RSYSLOG_DYNNAME.error.log" | head -10
+ echo "---last 10 lines are:"
+ cat -n "$RSYSLOG_DYNNAME.error.log" | tail -10
+ echo "UNSORTED data, first 10 lines are:"
+ cat -n "$RSYSLOG_DYNNAME.error.log" | head -10
+ echo "---last 10 lines are:"
+ cat -n "$RSYSLOG_DYNNAME.error.log" | tail -10
+ # for interactive testing, create a static filename. We know this may get
+ # mangled during a parallel test run
+ mv -f $RSYSLOG_DYNNAME.error.log error.log
+ error_exit 1
+ fi
+ return 0
+}
+
+
+# do the usual sequence check to see if everything was properly received. This is
+# a duplicateof seq-check, but we could not change its calling conventions without
+# breaking a lot of exitings test cases, so we preferred to duplicate the code here.
+# $4... are just to have the ability to pass in more options...
+# add -v to chkseq if you need more verbose output
+seq_check2() {
+ $RS_SORTCMD $RS_SORT_NUMERIC_OPT < ${RSYSLOG2_OUT_LOG} | ./chkseq -s$1 -e$2 $3 $4 $5 $6 $7
+ if [ "$?" -ne "0" ]; then
+ echo "sequence error detected"
+ error_exit 1
+ fi
+}
+
+
+# do the usual sequence check, but for gzip files
+# $4... are just to have the ability to pass in more options...
+gzip_seq_check() {
+ if [ "$1" == "" ]; then
+ if [ "$NUMMESSAGES" == "" ]; then
+ printf 'FAIL: gzip_seq_check called without parameters but NUMMESSAGES is unset!\n'
+ error_exit 100
+ fi
+ # use default parameters
+ startnum=0
+ endnum=$(( NUMMESSAGES - 1 ))
+ else
+ startnum=$1
+ endnum=$2
+ fi
+ ls -l ${RSYSLOG_OUT_LOG}
+ gunzip < ${RSYSLOG_OUT_LOG} | $RS_SORTCMD $RS_SORT_NUMERIC_OPT | ./chkseq -v -s$startnum -e$endnum $3 $4 $5 $6 $7
+ if [ "$?" -ne "0" ]; then
+ echo "sequence error detected"
+ error_exit 1
+ fi
+}
+
+
+# do a tcpflood run and check if it worked params are passed to tcpflood
+tcpflood() {
+ if [ "$1" == "--check-only" ]; then
+ check_only="yes"
+ shift
+ else
+ check_only="no"
+ fi
+ eval ./tcpflood -p$TCPFLOOD_PORT "$@" $TCPFLOOD_EXTRA_OPTS
+ res=$?
+ if [ "$check_only" == "yes" ]; then
+ if [ "$res" -ne "0" ]; then
+ echo "error during tcpflood on port ${TCPFLOOD_PORT}! But test continues..."
+ fi
+ return 0
+ else
+ if [ "$res" -ne "0" ]; then
+ echo "error during tcpflood on port ${TCPFLOOD_PORT}! see ${RSYSLOG_OUT_LOG}.save for what was written"
+ cp ${RSYSLOG_OUT_LOG} ${RSYSLOG_OUT_LOG}.save
+ error_exit 1 stacktrace
+ fi
+ fi
+}
+
+
+# cleanup
+# detect any left-over hanging instance
+exit_test() {
+ nhanging=0
+ #for pid in $(ps -eo pid,args|grep '/tools/[r]syslogd ' |sed -e 's/\( *\)\([0-9]*\).*/\2/');
+ #do
+ #echo "ERROR: left-over instance $pid, killing it"
+ # ps -fp $pid
+ # pwd
+ # printf "we do NOT kill the instance as this does not work with multiple\n"
+ # printf "builds per machine - this message is now informational to show prob exists!\n"
+ # #kill -9 $pid
+ # let "nhanging++"
+ #done
+ if test $nhanging -ne 0
+ then
+ echo "ABORT! hanging instances left at exit"
+ #error_exit 1
+ #exit 77 # for now, just skip - TODO: reconsider when supporting -j
+ fi
+ # now real cleanup
+ rm -f rsyslog.action.*.include
+ rm -f work rsyslog.out.* xlate*.lkp_tbl
+ rm -rf test-logdir stat-file1
+ rm -f rsyslog.conf.tlscert stat-file1 rsyslog.empty imfile-state:*
+ rm -f ${TESTCONF_NM}.conf
+ rm -f tmp.qi nocert
+ rm -fr $RSYSLOG_DYNNAME* # delete all of our dynamic files
+ unset TCPFLOOD_EXTRA_OPTS
+
+ # Extended Exit handling for kafka / zookeeper instances
+ kafka_exit_handling "true"
+
+ # Ensure redis is stopped
+ stop_redis
+
+ printf '%s Test %s SUCCESSFUL (took %s seconds)\n' "$(tb_timestamp)" "$0" "$(( $(date +%s) - TB_STARTTEST ))"
+ echo -------------------------------------------------------------------------------
+ exit 0
+}
+
+# finds a free port that we can bind a listener to
+# Obviously, any solution is race as another process could start
+# just after us and grab the same port. However, in practice it seems
+# to work pretty well. In any case, we should probably call this as
+# late as possible before the usage of the port.
+get_free_port() {
+$PYTHON -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()'
+}
+
+
+# return the inode number of file $1; file MUST exist
+get_inode() {
+ if [ ! -f "$1" ]; then
+ printf 'FAIL: file "%s" does not exist in get_inode\n' "$1"
+ error_exit 100
+ fi
+ $PYTHON -c 'import os; import stat; print(os.lstat("'$1'")[stat.ST_INO])'
+}
+
+
+# check that logger supports -d option, if not skip test
+# right now this is a bit dirty, we check distros which do not support it
+check_logger_has_option_d() {
+ skip_platform "FreeBSD" "We need logger -d option, which we do not have on FreeBSD"
+ skip_platform "SunOS" "We need logger -d option, which we do not have on (all flavors of) Solaris"
+
+ # check also the case for busybox
+ logger --help 2>&1 | head -n1 | grep -q BusyBox
+ if [ $? -eq 0 ]; then
+ echo "We need logger -d option, which we do not have have on Busybox"
+ exit 77
+ fi
+}
+
+
+require_relpEngineSetTLSLibByName() {
+ ./have_relpEngineSetTLSLibByName
+ if [ $? -eq 1 ]; then
+ echo "relpEngineSetTLSLibByName API not available. Test stopped"
+ exit 77
+ fi;
+}
+
+require_relpEngineVersion() {
+ if [ "$1" == "" ]; then
+ echo "require_relpEngineVersion missing required parameter (minimum version required)"
+ exit 1
+ else
+ ./check_relpEngineVersion $1
+ if [ $? -eq 1 ]; then
+ echo "relpEngineVersion too OLD. Test stopped"
+ exit 77
+ fi;
+ fi
+}
+
+
+# check if command $1 is available - will exit 77 when not OK
+check_command_available() {
+ have_cmd=0
+ if [ "$1" == "timeout" ]; then
+ if timeout --version &>/dev/null ; then
+ have_cmd=1
+ fi
+ else
+ command -v $1
+ if [ $? -eq 0 ]; then
+ have_cmd=1
+ fi
+ fi
+ if [ $have_cmd -eq 0 ] ; then
+ printf 'Testbench requires unavailable command: %s\n' "$1"
+ exit 77 # do NOT error_exit here!
+ fi
+}
+
+
+# sort the output file just like we normally do it, but do not call
+# seqchk. This is needed for some operations where we need the sort
+# result for some preprocessing. Note that a later seqchk will sort
+# again, but that's not an issue.
+presort() {
+ rm -f $RSYSLOG_DYNNAME.presort
+ $RS_SORTCMD $RS_SORT_NUMERIC_OPT < ${RSYSLOG_OUT_LOG} > $RSYSLOG_DYNNAME.presort
+}
+
+
+#START: ext kafka config
+#dep_cache_dir=$(readlink -f .dep_cache)
+export RS_ZK_DOWNLOAD=apache-zookeeper-3.9.1-bin.tar.gz
+dep_cache_dir=$(pwd)/.dep_cache
+dep_zk_url=https://downloads.apache.org/zookeeper/zookeeper-3.9.1/$RS_ZK_DOWNLOAD
+dep_zk_cached_file=$dep_cache_dir/$RS_ZK_DOWNLOAD
+
+export RS_KAFKA_DOWNLOAD=kafka_2.13-2.8.0.tgz
+dep_kafka_url="https://www.rsyslog.com/files/download/rsyslog/$RS_KAFKA_DOWNLOAD"
+dep_kafka_cached_file=$dep_cache_dir/$RS_KAFKA_DOWNLOAD
+
+if [ -z "$ES_DOWNLOAD" ]; then
+ export ES_DOWNLOAD=elasticsearch-7.14.1-linux-x86_64.tar.gz
+fi
+if [ -z "$ES_PORT" ]; then
+ export ES_PORT=19200
+fi
+dep_es_cached_file="$dep_cache_dir/$ES_DOWNLOAD"
+
+# kafka (including Zookeeper)
+dep_kafka_dir_xform_pattern='s#^[^/]\+#kafka#g'
+dep_zk_dir_xform_pattern='s#^[^/]\+#zk#g'
+dep_es_dir_xform_pattern='s#^[^/]\+#es#g'
+#dep_kafka_log_dump=$(readlink -f rsyslog.out.kafka.log)
+
+# TODO Make dynamic work dir for multiple instances
+#dep_work_dir=$(readlink -f .dep_wrk)
+dep_work_dir=$(pwd)/.dep_wrk
+#dep_kafka_work_dir=$dep_work_dir/kafka
+#dep_zk_work_dir=$dep_work_dir/zk
+
+#END: ext kafka config
+
+kafka_exit_handling() {
+
+ # Extended Exit handling for kafka / zookeeper instances
+ if [[ "$EXTRA_EXIT" == 'kafka' ]]; then
+
+ echo "stop kafka instance"
+ stop_kafka '.dep_wrk' $1
+
+ echo "stop zookeeper instance"
+ stop_zookeeper '.dep_wrk' $1
+ fi
+
+ # Extended Exit handling for kafka / zookeeper instances
+ if [[ "$EXTRA_EXIT" == 'kafkamulti' ]]; then
+ echo "stop kafka instances"
+ stop_kafka '.dep_wrk1' $1
+ stop_kafka '.dep_wrk2' $1
+ stop_kafka '.dep_wrk3' $1
+
+ echo "stop zookeeper instances"
+ stop_zookeeper '.dep_wrk1' $1
+ stop_zookeeper '.dep_wrk2' $1
+ stop_zookeeper '.dep_wrk3' $1
+ fi
+}
+
+download_kafka() {
+ if [ ! -d $dep_cache_dir ]; then
+ echo "Creating dependency cache dir $dep_cache_dir"
+ mkdir $dep_cache_dir
+ fi
+ if [ ! -f $dep_zk_cached_file ]; then
+ if [ -f /local_dep_cache/$RS_ZK_DOWNLOAD ]; then
+ printf 'Zookeeper: satisfying dependency %s from system cache.\n' "$RS_ZK_DOWNLOAD"
+ cp /local_dep_cache/$RS_ZK_DOWNLOAD $dep_zk_cached_file
+ else
+ echo "Downloading zookeeper"
+ echo wget -q $dep_zk_url -O $dep_zk_cached_file
+ wget -q $dep_zk_url -O $dep_zk_cached_file
+ if [ $? -ne 0 ]
+ then
+ echo error during wget, retry:
+ wget $dep_zk_url -O $dep_zk_cached_file
+ if [ $? -ne 0 ]
+ then
+ error_exit 1
+ fi
+ fi
+ fi
+ fi
+ if [ ! -f $dep_kafka_cached_file ]; then
+ if [ -f /local_dep_cache/$RS_KAFKA_DOWNLOAD ]; then
+ printf 'Kafka: satisfying dependency %s from system cache.\n' "$RS_KAFKA_DOWNLOAD"
+ cp /local_dep_cache/$RS_KAFKA_DOWNLOAD $dep_kafka_cached_file
+ else
+ echo "Downloading kafka"
+ wget -q $dep_kafka_url -O $dep_kafka_cached_file
+ if [ $? -ne 0 ]
+ then
+ echo error during wget, retry:
+ wget $dep_kafka_url -O $dep_kafka_cached_file
+ if [ $? -ne 0 ]
+ then
+ rm $dep_kafka_cached_file # a 0-size file may be left over
+ error_exit 1
+ fi
+ fi
+ fi
+ fi
+}
+
+stop_kafka() {
+ if [ "$KEEP_KAFKA_RUNNING" == "YES" ]; then
+ return
+ fi
+ i=0
+ if [ "x$1" == "x" ]; then
+ dep_work_dir=$(readlink -f .dep_wrk)
+ dep_work_kafka_config="kafka-server.properties"
+ else
+ dep_work_dir=$(readlink -f $srcdir/$1)
+ if [[ ".dep_wrk" != "$1" ]]; then
+ dep_work_kafka_config="kafka-server$1.properties"
+ else
+ dep_work_kafka_config="kafka-server.properties"
+ fi
+ fi
+ if [ ! -d $dep_work_dir/kafka ]; then
+ echo "Kafka work-dir $dep_work_dir/kafka does not exist, no action needed"
+ else
+ # shellcheck disable=SC2009 - we do not grep on the process name!
+ kafkapid=$(ps aux | grep -i $dep_work_kafka_config | grep java | grep -v grep | awk '{print $2}')
+
+ echo "Stopping Kafka instance $1 ($dep_work_kafka_config/$kafkapid)"
+ kill $kafkapid
+
+ # Check if kafka instance went down!
+ while true; do
+ # shellcheck disable=SC2009 - we do not grep on the process name!
+ kafkapid=$(ps aux | grep -i $dep_work_kafka_config | grep java | grep -v grep | awk '{print $2}')
+ if [[ "" != "$kafkapid" ]]; then
+ $TESTTOOL_DIR/msleep 100 # wait 100 milliseconds
+ if test $i -gt $TB_TIMEOUT_STARTSTOP; then
+ echo "Kafka instance $dep_work_kafka_config (PID $kafkapid) still running - Performing hard shutdown (-9)"
+ kill -9 $kafkapid
+ break
+ fi
+ (( i++ ))
+ else
+ # Break the loop
+ break
+ fi
+ done
+
+ if [[ "$2" == 'true' ]]; then
+ # Process shutdown, do cleanup now
+ cleanup_kafka $1
+ fi
+ fi
+}
+
+cleanup_kafka() {
+ if [ "x$1" == "x" ]; then
+ dep_work_dir=$(readlink -f .dep_wrk)
+ else
+ dep_work_dir=$(readlink -f $srcdir/$1)
+ fi
+ if [ ! -d $dep_work_dir/kafka ]; then
+ echo "Kafka work-dir $dep_work_dir/kafka does not exist, no action needed"
+ else
+ echo "Cleanup Kafka instance $1"
+ rm -rf $dep_work_dir/kafka
+ fi
+}
+
+stop_zookeeper() {
+ if [ "$KEEP_KAFKA_RUNNING" == "YES" ]; then
+ return
+ fi
+ i=0
+ if [ "x$1" == "x" ]; then
+ dep_work_dir=$(readlink -f .dep_wrk)
+ dep_work_tk_config="zoo.cfg"
+ else
+ dep_work_dir=$(readlink -f $srcdir/$1)
+ if [[ ".dep_wrk" != "$1" ]]; then
+ dep_work_tk_config="zoo$1.cfg"
+ else
+ dep_work_tk_config="zoo.cfg"
+ fi
+ fi
+
+ if [ ! -d $dep_work_dir/zk ]; then
+ echo "Zookeeper work-dir $dep_work_dir/zk does not exist, no action needed"
+ else
+ # Get Zookeeper pid instance
+ zkpid=$(ps aux | grep -i $dep_work_tk_config | grep java | grep -v grep | awk '{print $2}')
+ echo "Stopping Zookeeper instance $1 ($dep_work_tk_config/$zkpid)"
+ kill $zkpid
+
+ # Check if Zookeeper instance went down!
+ zkpid=$(ps aux | grep -i $dep_work_tk_config | grep java | grep -v grep | awk '{print $2}')
+ if [[ "" != "$zkpid" ]]; then
+ while true; do
+ zkpid=$(ps aux | grep -i $dep_work_tk_config | grep java | grep -v grep | awk '{print $2}')
+ if [[ "" != "$zkpid" ]]; then
+ $TESTTOOL_DIR/msleep 100 # wait 100 milliseconds
+ if test $i -gt $TB_TIMEOUT_STARTSTOP; then
+ echo "Zookeeper instance $dep_work_tk_config (PID $zkpid) still running - Performing hard shutdown (-9)"
+ kill -9 $zkpid
+ break
+ fi
+ (( i++ ))
+ else
+ break
+ fi
+ done
+ fi
+
+ if [[ "$2" == 'true' ]]; then
+ # Process shutdown, do cleanup now
+ cleanup_zookeeper $1
+ fi
+ rm "$ZOOPIDFILE"
+ fi
+}
+
+cleanup_zookeeper() {
+ if [ "x$1" == "x" ]; then
+ dep_work_dir=$(readlink -f .dep_wrk)
+ else
+ dep_work_dir=$(readlink -f $srcdir/$1)
+ fi
+ rm -rf $dep_work_dir/zk
+}
+
+start_zookeeper() {
+ if [ "$KEEP_KAFKA_RUNNING" == "YES" ] && [ -f "$ZOOPIDFILE" ]; then
+ if kill -0 "$(cat "$ZOOPIDFILE")"; then
+ printf 'zookeeper already running, no need to start\n'
+ return
+ else
+ printf 'INFO: zookeeper pidfile %s exists, but zookeeper not running\n' "$ZOOPIDFILE"
+ printf 'deleting pid file\n'
+ rm -f "$ZOOPIDFILE"
+ fi
+ fi
+ if [ "x$1" == "x" ]; then
+ dep_work_dir=$(readlink -f .dep_wrk)
+ dep_work_tk_config="zoo.cfg"
+ else
+ dep_work_dir=$(readlink -f $srcdir/$1)
+ dep_work_tk_config="zoo$1.cfg"
+ fi
+
+ if [ ! -f $dep_zk_cached_file ]; then
+ echo "Dependency-cache does not have zookeeper package, did you download dependencies?"
+ error_exit 77
+ fi
+ if [ ! -d $dep_work_dir ]; then
+ echo "Creating dependency working directory"
+ mkdir -p $dep_work_dir
+ fi
+ if [ -d $dep_work_dir/zk ]; then
+ (cd $dep_work_dir/zk && ./bin/zkServer.sh stop)
+ $TESTTOOL_DIR/msleep 2000
+ fi
+ rm -rf $dep_work_dir/zk
+ (cd $dep_work_dir && tar -zxvf $dep_zk_cached_file --xform $dep_zk_dir_xform_pattern --show-transformed-names) > /dev/null
+ cp -f $srcdir/testsuites/$dep_work_tk_config $dep_work_dir/zk/conf/zoo.cfg
+ echo "Starting Zookeeper instance $1"
+ (cd $dep_work_dir/zk && ./bin/zkServer.sh start)
+ wait_startup_pid "$ZOOPIDFILE"
+}
+
+start_kafka() {
+ printf '%s starting kafka\n' "$(tb_timestamp)"
+
+ # Force IPv4 usage of Kafka!
+ export KAFKA_HEAP_OPTS="-Xms256m -Xmx256m" # we need to take care for smaller CI systems!
+ export KAFKA_OPTS="-Djava.net.preferIPv4Stack=True"
+ if [ "x$1" == "x" ]; then
+ dep_work_dir=$(readlink -f .dep_wrk)
+ dep_work_kafka_config="kafka-server.properties"
+ else
+ dep_work_dir=$(readlink -f $1)
+ dep_work_kafka_config="kafka-server$1.properties"
+ fi
+
+ # shellcheck disable=SC2009 - we do not grep on the process name!
+ kafkapid=$(ps aux | grep -i $dep_work_kafka_config | grep java | grep -v grep | awk '{print $2}')
+ if [ "$KEEP_KAFKA_RUNNING" == "YES" ] && [ "$kafkapid" != "" ]; then
+ printf 'kafka already running, no need to start\n'
+ return
+ fi
+
+ if [ ! -f $dep_kafka_cached_file ]; then
+ echo "Dependency-cache does not have kafka package, did you download dependencies?"
+ error_exit 77
+ fi
+ if [ ! -d $dep_work_dir ]; then
+ echo "Creating dependency working directory"
+ mkdir -p $dep_work_dir
+ fi
+ rm -rf $dep_work_dir/kafka
+ ( cd $dep_work_dir &&
+ tar -zxvf $dep_kafka_cached_file --xform $dep_kafka_dir_xform_pattern --show-transformed-names) > /dev/null
+ cp -f $srcdir/testsuites/$dep_work_kafka_config $dep_work_dir/kafka/config/
+ #if [ "$(ps aux | grep -i $dep_work_kafka_config | grep java | grep -v grep | awk '{print $2}')" != "" ]; then
+ echo "Starting Kafka instance $dep_work_kafka_config"
+ (cd $dep_work_dir/kafka && ./bin/kafka-server-start.sh -daemon ./config/$dep_work_kafka_config)
+ $TESTTOOL_DIR/msleep 4000
+
+ # Check if kafka instance came up!
+ # shellcheck disable=SC2009 - we do not grep on the process name!
+ kafkapid=$(ps aux | grep -i $dep_work_kafka_config | grep java | grep -v grep | awk '{print $2}')
+ if [[ "" != "$kafkapid" ]];
+ then
+ echo "Kafka instance $dep_work_kafka_config (PID $kafkapid) started ... "
+ else
+ echo "Starting Kafka instance $dep_work_kafka_config, SECOND ATTEMPT!"
+ (cd $dep_work_dir/kafka && ./bin/kafka-server-start.sh -daemon ./config/$dep_work_kafka_config)
+ $TESTTOOL_DIR/msleep 4000
+
+ # shellcheck disable=SC2009 - we do not grep on the process name!
+ kafkapid=$(ps aux | grep -i $dep_work_kafka_config | grep java | grep -v grep | awk '{print $2}')
+ if [[ "" != "$kafkapid" ]];
+ then
+ echo "Kafka instance $dep_work_kafka_config (PID $kafkapid) started ... "
+ else
+ echo "Failed to start Kafka instance for $dep_work_kafka_config"
+ echo "displaying all kafka logs now:"
+ for logfile in $dep_work_dir/logs/*; do
+ echo "FILE: $logfile"
+ cat $logfile
+ done
+ error_exit 77
+ fi
+ fi
+}
+
+create_kafka_topic() {
+ if [ "x$2" == "x" ]; then
+ dep_work_dir=$(readlink -f .dep_wrk)
+ else
+ dep_work_dir=$(readlink -f $2)
+ fi
+ if [ "x$3" == "x" ]; then
+ dep_work_port='2181'
+ else
+ dep_work_port=$3
+ fi
+ if [ ! -d $dep_work_dir/kafka ]; then
+ echo "Kafka work-dir $dep_work_dir/kafka does not exist, did you start kafka?"
+ exit 1
+ fi
+ if [ "x$1" == "x" ]; then
+ echo "Topic-name not provided."
+ exit 1
+ fi
+
+ # we need to make sure replication has is working. So let's loop until no more
+ # errors (or timeout) - see also: https://github.com/rsyslog/rsyslog/issues/3045
+ timeout_ready=100 # roughly 10 sec
+ is_retry=0
+ i=0
+ while true; do
+ text=$(cd $dep_work_dir/kafka && ./bin/kafka-topics.sh --zookeeper localhost:$dep_work_port/kafka --create --topic $1 --replication-factor 1 --partitions 2 )
+ grep "Error.* larger than available brokers: 0" <<<"$text"
+ res=$?
+ if [ $res -ne 0 ]; then
+ echo looks like brokers are available - continue...
+ break
+ fi
+ $TESTTOOL_DIR/msleep 100 # wait 100 milliseconds
+ (( i++ ))
+ if test $i -gt $timeout_ready; then
+ echo "ENV ERROR: kafka brokers did not come up:"
+ cat -n <<< $text
+ if [ $is_retry == 1 ]; then
+ echo "SKIPing test as the env is not ready for it"
+ exit 177
+ fi
+ echo "RETRYING kafka startup, doing shutdown and startup"
+ stop_zookeeper ""; stop_kafka ""
+ start_zookeeper ""; start_kafka ""
+ echo "READY for RETRY"
+ is_retry=1
+ i=0
+ fi
+ done
+
+ # we *assume* now all goes well
+ (cd $dep_work_dir/kafka && ./bin/kafka-topics.sh --zookeeper localhost:$dep_work_port/kafka --alter --topic $1 --delete-config retention.ms)
+ (cd $dep_work_dir/kafka && ./bin/kafka-topics.sh --zookeeper localhost:$dep_work_port/kafka --alter --topic $1 --delete-config retention.bytes)
+}
+
+delete_kafka_topic() {
+ if [ "x$2" == "x" ]; then
+ dep_work_dir=$(readlink -f .dep_wrk)
+ else
+ dep_work_dir=$(readlink -f $srcdir/$2)
+ fi
+ if [ "x$3" == "x" ]; then
+ dep_work_port='2181'
+ else
+ dep_work_port=$3
+ fi
+
+ echo "deleting kafka-topic $1"
+ (cd $dep_work_dir/kafka && ./bin/kafka-topics.sh --delete --zookeeper localhost:$dep_work_port/kafka --topic $1)
+}
+
+dump_kafka_topic() {
+ if [ "x$2" == "x" ]; then
+ dep_work_dir=$(readlink -f .dep_wrk)
+ dep_kafka_log_dump=$(readlink -f rsyslog.out.kafka.log)
+ else
+ dep_work_dir=$(readlink -f $srcdir/$2)
+ dep_kafka_log_dump=$(readlink -f rsyslog.out.kafka$2.log)
+ fi
+ if [ "x$3" == "x" ]; then
+ dep_work_port='2181'
+ else
+ dep_work_port=$3
+ fi
+
+ echo "dumping kafka-topic $1"
+ if [ ! -d $dep_work_dir/kafka ]; then
+ echo "Kafka work-dir does not exist, did you start kafka?"
+ exit 1
+ fi
+ if [ "x$1" == "x" ]; then
+ echo "Topic-name not provided."
+ exit 1
+ fi
+
+ (cd $dep_work_dir/kafka && ./bin/kafka-console-consumer.sh --timeout-ms 2000 --from-beginning --zookeeper localhost:$dep_work_port/kafka --topic $1 > $dep_kafka_log_dump)
+}
+
+dump_kafka_serverlog() {
+ if [ "x$1" == "x" ]; then
+ dep_work_dir=$(readlink -f .dep_wrk)
+ else
+ dep_work_dir=$(readlink -f $srcdir/$1)
+ fi
+ if [ ! -d $dep_work_dir/kafka ]; then
+ echo "Kafka work-dir $dep_work_dir/kafka does not exist, no kafka debuglog"
+ else
+ echo "Dumping server.log from Kafka instance $1"
+ echo "========================================="
+ cat $dep_work_dir/kafka/logs/server.log
+ echo "========================================="
+ printf 'non-info is:\n'
+ grep --invert-match '^\[.* INFO ' $dep_work_dir/kafka/logs/server.log | grep '^\['
+ fi
+}
+
+dump_zookeeper_serverlog() {
+ if [ "x$1" == "x" ]; then
+ dep_work_dir=$(readlink -f .dep_wrk)
+ else
+ dep_work_dir=$(readlink -f $srcdir/$1)
+ fi
+ echo "Dumping zookeeper.out from Zookeeper instance $1"
+ echo "========================================="
+ cat $dep_work_dir/zk/zookeeper.out
+ echo "========================================="
+ printf 'non-info is:\n'
+ grep --invert-match '^\[.* INFO ' $dep_work_dir/zk/zookeeper.out | grep '^\['
+}
+
+
+# download elasticsearch files, if necessary
+download_elasticsearch() {
+ if [ ! -d $dep_cache_dir ]; then
+ echo "Creating dependency cache dir $dep_cache_dir"
+ mkdir $dep_cache_dir
+ fi
+ if [ ! -f $dep_es_cached_file ]; then
+ if [ -f /local_dep_cache/$ES_DOWNLOAD ]; then
+ printf 'ElasticSearch: satisfying dependency %s from system cache.\n' "$ES_DOWNLOAD"
+ cp /local_dep_cache/$ES_DOWNLOAD $dep_es_cached_file
+ else
+ dep_es_url="https://www.rsyslog.com/files/download/rsyslog/$ES_DOWNLOAD"
+ printf 'ElasticSearch: satisfying dependency %s from %s\n' "$ES_DOWNLOAD" "$dep_es_url"
+ wget -q $dep_es_url -O $dep_es_cached_file
+ fi
+ fi
+}
+
+
+# prepare elasticsearch execution environment
+# this also stops any previous elasticsearch instance, if found
+prepare_elasticsearch() {
+ stop_elasticsearch # stop if it is still running
+ # Heap Size (limit to 128MB for testbench! default is way to HIGH)
+ export ES_JAVA_OPTS="-Xms128m -Xmx128m"
+
+ dep_work_dir=$(readlink -f .dep_wrk)
+ dep_work_es_config="es.yml"
+ dep_work_es_pidfile="es.pid"
+
+ if [ ! -f $dep_es_cached_file ]; then
+ echo "Dependency-cache does not have elasticsearch package, did "
+ echo "you download dependencies?"
+ error_exit 100
+ fi
+ if [ ! -d $dep_work_dir ]; then
+ echo "Creating dependency working directory"
+ mkdir -p $dep_work_dir
+ fi
+ if [ -d $dep_work_dir/es ]; then
+ if [ -e $dep_work_es_pidfile ]; then
+ es_pid=$(cat $dep_work_es_pidfile)
+ kill -SIGTERM $es_pid
+ wait_pid_termination $es_pid
+ fi
+ fi
+ rm -rf $dep_work_dir/es
+ echo TEST USES ELASTICSEARCH BINARY $dep_es_cached_file
+ (cd $dep_work_dir && tar -zxf $dep_es_cached_file --xform $dep_es_dir_xform_pattern --show-transformed-names) > /dev/null
+ if [ -n "${ES_PORT:-}" ] ; then
+ rm -f $dep_work_dir/es/config/elasticsearch.yml
+ sed "s/^http.port:.*\$/http.port: ${ES_PORT}/" $srcdir/testsuites/$dep_work_es_config > $dep_work_dir/es/config/elasticsearch.yml
+ if [ "$ES_DOWNLOAD" != "elasticsearch-6.0.0.tar.gz" ]; then
+ printf 'xpack.security.enabled: false\n' >> $dep_work_dir/es/config/elasticsearch.yml
+ fi
+ else
+ cp -f $srcdir/testsuites/$dep_work_es_config $dep_work_dir/es/config/elasticsearch.yml
+ fi
+
+ # Avoid deprecated parameter, new option introduced with 6.7
+ echo "Setting transport tcp option to ${ES_PORT_OPTION:-transport.tcp.port}"
+ sed -i "s/transport.tcp.port/${ES_PORT_OPTION:-transport.tcp.port}/g" "$dep_work_dir/es/config/elasticsearch.yml"
+
+ if [ ! -d $dep_work_dir/es/data ]; then
+ echo "Creating elastic search directories"
+ mkdir -p $dep_work_dir/es/data
+ mkdir -p $dep_work_dir/es/logs
+ mkdir -p $dep_work_dir/es/tmp
+ fi
+ echo ElasticSearch prepared for use in test.
+}
+
+
+# ensure that a basic, suitable instance of elasticsearch is running. This is part
+# of an effort to avoid restarting elasticsearch more often than necessary.
+ensure_elasticsearch_ready() {
+ if printf '%s:%s:%s\n' "$ES_DOWNLOAD" "$ES_PORT" "$(cat es.pid)" \
+ | cmp -b - elasticsearch.running
+ then
+ printf 'Elasticsearch already running, NOT restarting it\n'
+ else
+ cat elasticsearch.running
+ cleanup_elasticsearch
+ dep_es_cached_file="$dep_cache_dir/$ES_DOWNLOAD"
+ download_elasticsearch
+ prepare_elasticsearch
+ if [ "$1" != "--no-start" ]; then
+ start_elasticsearch
+ printf '%s:%s:%s\n' "$ES_DOWNLOAD" "$ES_PORT" "$(cat es.pid)" > elasticsearch.running
+ fi
+ fi
+ if [ "$1" != "--no-start" ]; then
+ printf 'running elasticsearch instance: %s\n' "$(cat elasticsearch.running)"
+ init_elasticsearch
+ fi
+}
+
+
+# $2, if set, is the number of additional ES instances
+start_elasticsearch() {
+ # Heap Size (limit to 256MB for testbench! defaults is way to HIGH)
+ export ES_JAVA_OPTS="-Xms256m -Xmx256m"
+
+ dep_work_dir=$(readlink -f .dep_wrk)
+ dep_work_es_config="es.yml"
+ dep_work_es_pidfile="$(pwd)/es.pid"
+ echo "Starting ElasticSearch"
+
+ # THIS IS THE ACTUAL START of ES
+ $dep_work_dir/es/bin/elasticsearch -p $dep_work_es_pidfile -d
+ $TESTTOOL_DIR/msleep 2000
+ wait_startup_pid $dep_work_es_pidfile
+ printf 'elasticsearch pid is %s\n' "$(cat $dep_work_es_pidfile)"
+
+ # Wait for startup with hardcoded timeout
+ timeoutend=120
+ timeseconds=0
+ # Loop until elasticsearch port is reachable or until
+ # timeout is reached!
+ until [ "$(curl --silent --show-error --connect-timeout 1 http://localhost:${ES_PORT:-19200} | grep 'rsyslog-testbench')" != "" ]; do
+ echo "--- waiting for ES startup: $timeseconds seconds"
+ $TESTTOOL_DIR/msleep 1000
+ (( timeseconds=timeseconds + 1 ))
+
+ if [ "$timeseconds" -gt "$timeoutend" ]; then
+ echo "--- TIMEOUT ( $timeseconds ) reached!!!"
+ if [ ! -d $dep_work_dir/es ]; then
+ echo "ElasticSearch $dep_work_dir/es does not exist, no ElasticSearch debuglog"
+ else
+ echo "Dumping rsyslog-testbench.log from ElasticSearch instance $1"
+ echo "========================================="
+ cat $dep_work_dir/es/logs/rsyslog-testbench.log
+ echo "========================================="
+# printf 'non-info is:\n'
+# grep --invert-match '^\[.* INFO ' $dep_work_dir/kafka/logs/server.log | grep '^\['
+ fi
+ error_exit 1
+ fi
+ done
+ $TESTTOOL_DIR/msleep 2000
+ echo ES startup succeeded
+}
+
+# read data from ES to a local file so that we can process
+# $1 - number of records (ES does not return all records unless you tell it explicitly).
+# $2 - ES port
+es_getdata() {
+ curl --silent -XPUT --show-error -H 'Content-Type: application/json' "http://localhost:${2:-$ES_PORT}/rsyslog_testbench/_settings" -d '{ "index" : { "max_result_window" : '${1:-$NUMMESSAGES}' } }'
+ # refresh to ensure we get the latest data
+ curl --silent localhost:${2:-$ES_PORT}/rsyslog_testbench/_refresh
+ curl --silent localhost:${2:-$ES_PORT}/rsyslog_testbench/_search?size=${1:-$NUMMESSAGES} > $RSYSLOG_DYNNAME.work
+ $PYTHON $srcdir/es_response_get_msgnum.py > ${RSYSLOG_OUT_LOG}
+}
+
+# a standard method to support shutdown & queue empty check for a wide range
+# of elasticsearch tests. This works if we assume that ES has delivered messages
+# to the default location.
+es_shutdown_empty_check() {
+ es_getdata $NUMMESSAGES $ES_PORT
+ lines=$(wc -l < "$RSYSLOG_OUT_LOG")
+ if [ "$lines" -eq $NUMMESSAGES ]; then
+ printf '%s es_shutdown_empty_check: success, have %d lines\n' "$(tb_timestamp)" $lines
+ return 0
+ fi
+ printf '%s es_shutdown_empty_check: have %d lines, expecting %d\n' "$(tb_timestamp)" $lines $NUMMESSAGES
+ return 1
+}
+
+
+stop_elasticsearch() {
+ dep_work_dir=$(readlink -f $srcdir)
+ dep_work_es_pidfile="es.pid"
+ rm elasticsearch.running
+ if [ -e $dep_work_es_pidfile ]; then
+ es_pid=$(cat $dep_work_es_pidfile)
+ printf 'stopping ES with pid %d\n' $es_pid
+ kill -SIGTERM $es_pid
+ wait_pid_termination $es_pid
+ fi
+}
+
+# cleanup es leftovers when it is being stopped
+cleanup_elasticsearch() {
+ dep_work_dir=$(readlink -f .dep_wrk)
+ dep_work_es_pidfile="es.pid"
+ stop_elasticsearch
+ rm -f $dep_work_es_pidfile
+ rm -rf $dep_work_dir/es
+}
+
+# initialize local Elasticsearch *testbench* instance for the next
+# test. NOTE: do NOT put anything useful on that instance!
+init_elasticsearch() {
+ curl --silent -XDELETE localhost:${ES_PORT:-9200}/rsyslog_testbench
+}
+
+omhttp_start_server() {
+ # Args: 1=port 2=server args
+ # Args 2 and up are passed along as is to omhttp_server.py
+ omhttp_server_py=$srcdir/omhttp_server.py
+ if [ ! -f $omhttp_server_py ]; then
+ echo "Cannot find ${omhttp_server_py} for omhttp test"
+ error_exit 1
+ fi
+
+ if [ "x$1" == "x" ]; then
+ omhttp_server_port="8080"
+ else
+ omhttp_server_port="$1"
+ fi
+
+ # Create work directory for parallel tests
+ omhttp_work_dir=$RSYSLOG_DYNNAME/omhttp
+
+ omhttp_server_pidfile="${omhttp_work_dir}/omhttp_server.pid"
+ omhttp_server_logfile="${omhttp_work_dir}/omhttp_server.log"
+ mkdir -p ${omhttp_work_dir}
+
+ server_args="-p $omhttp_server_port ${*:2} --port-file $RSYSLOG_DYNNAME.omhttp_server_lstnport.file"
+
+ timeout 30m $PYTHON ${omhttp_server_py} ${server_args} >> ${omhttp_server_logfile} 2>&1 &
+ if [ ! $? -eq 0 ]; then
+ echo "Failed to start omhttp test server."
+ rm -rf $omhttp_work_dir
+ error_exit 1
+ fi
+ omhttp_server_pid=$!
+
+ wait_file_exists "$RSYSLOG_DYNNAME.omhttp_server_lstnport.file"
+ omhttp_server_lstnport="$(cat $RSYSLOG_DYNNAME.omhttp_server_lstnport.file)"
+ echo ${omhttp_server_pid} > ${omhttp_server_pidfile}
+ echo "Started omhttp test server with args ${server_args} with pid ${omhttp_server_pid}, port {$omhttp_server_lstnport}"
+}
+
+omhttp_stop_server() {
+ # Args: None
+ omhttp_work_dir=$RSYSLOG_DYNNAME/omhttp
+ if [ ! -d $omhttp_work_dir ]; then
+ echo "omhttp server $omhttp_work_dir does not exist, no action needed"
+ else
+ echo "Stopping omhttp server"
+ kill -9 $(cat ${omhttp_work_dir}/omhttp_server.pid) > /dev/null 2>&1
+ rm -rf $omhttp_work_dir
+ fi
+}
+
+omhttp_get_data() {
+ # Args: 1=port 2=endpoint 3=batchformat(optional)
+ if [ "x$1" == "x" ]; then
+ omhttp_server_port=8080
+ else
+ omhttp_server_port=$1
+ fi
+
+ if [ "x$2" == "x" ]; then
+ omhttp_path=""
+ else
+ omhttp_path=$2
+ fi
+
+ # The test server returns a json encoded array of strings containing whatever omhttp sent to it in each request
+ python_init="import json, sys; dat = json.load(sys.stdin)"
+ python_print="print('\n'.join(out))"
+ if [ "x$3" == "x" ]; then
+ # dat = ['{"msgnum":"1"}, '{"msgnum":"2"}', '{"msgnum":"3"}', '{"msgnum":"4"}']
+ python_parse="$python_init; out = [json.loads(l)['msgnum'] for l in dat]; $python_print"
+ else
+ if [ "x$3" == "xjsonarray" ]; then
+ # dat = ['[{"msgnum":"1"},{"msgnum":"2"}]', '[{"msgnum":"3"},{"msgnum":"4"}]']
+ python_parse="$python_init; out = [l['msgnum'] for a in dat for l in json.loads(a)]; $python_print"
+ elif [ "x$3" == "xnewline" ]; then
+ # dat = ['{"msgnum":"1"}\n{"msgnum":"2"}', '{"msgnum":"3"}\n{"msgnum":"4"}']
+ python_parse="$python_init; out = [json.loads(l)['msgnum'] for a in dat for l in a.split('\n')]; $python_print"
+ elif [ "x$3" == "xkafkarest" ]; then
+ # dat = ['{"records":[{"value":{"msgnum":"1"}},{"value":{"msgnum":"2"}}]}',
+ # '{"records":[{"value":{"msgnum":"3"}},{"value":{"msgnum":"4"}}]}']
+ python_parse="$python_init; out = [l['value']['msgnum'] for a in dat for l in json.loads(a)['records']]; $python_print"
+ elif [ "x$3" == "xlokirest" ]; then
+ # dat = ['{"streams":[{"msgnum":"1"},{"msgnum":"2"}]}',
+ # '{"streams":[{"msgnum":"3"},{"msgnum":"4"}]}']
+ python_parse="$python_init; out = [l['msgnum'] for a in dat for l in json.loads(a)['streams']]; $python_print"
+ else
+ # use newline parsing as default
+ python_parse="$python_init; out = [json.loads(l)['msgnum'] for a in dat for l in a.split('\n')]; $python_print"
+ fi
+
+ fi
+
+ omhttp_url="localhost:${omhttp_server_port}/${omhttp_path}"
+ curl -s ${omhttp_url} \
+ | $PYTHON -c "${python_parse}" | sort -n \
+ > ${RSYSLOG_OUT_LOG}
+}
+
+
+# prepare MySQL for next test
+# each test receives its own database so that we also can run in parallel
+mysql_prep_for_test() {
+ mysql -u rsyslog --password=testbench -e "CREATE DATABASE $RSYSLOG_DYNNAME; "
+ mysql -u rsyslog --password=testbench --database $RSYSLOG_DYNNAME \
+ -e "CREATE TABLE SystemEvents (ID int unsigned not null auto_increment primary key, CustomerID bigint,ReceivedAt datetime NULL,DeviceReportedTime datetime NULL,Facility smallint NULL,Priority smallint NULL,FromHost varchar(60) NULL,Message text,NTSeverity int NULL,Importance int NULL,EventSource varchar(60),EventUser varchar(60) NULL,EventCategory int NULL,EventID int NULL,EventBinaryData text NULL,MaxAvailable int NULL,CurrUsage int NULL,MinUsage int NULL,MaxUsage int NULL,InfoUnitID int NULL,SysLogTag varchar(60),EventLogType varchar(60),GenericFileName VarChar(60),SystemID int NULL); CREATE TABLE SystemEventsProperties (ID int unsigned not null auto_increment primary key,SystemEventID int NULL,ParamName varchar(255) NULL,ParamValue text NULL);"
+ mysql --user=rsyslog --password=testbench --database $RSYSLOG_DYNNAME \
+ -e "truncate table SystemEvents;"
+ # TEST ONLY:
+ #mysql -s --user=rsyslog --password=testbench --database $RSYSLOG_DYNNAME \
+ #-e "select substring(Message,9,8) from SystemEvents;"
+ # END TEST
+ printf 'mysql ready for test, database: %s\n' $RSYSLOG_DYNNAME
+}
+
+# get data from mysql DB so that we can do seq_check on it.
+mysql_get_data() {
+ # note "-s" is required to suppress the select "field header"
+ mysql -s --user=rsyslog --password=testbench --database $RSYSLOG_DYNNAME \
+ -e "select substring(Message,9,8) from SystemEvents;" \
+ > $RSYSLOG_OUT_LOG 2> "$RSYSLOG_DYNNAME.mysqlerr"
+ grep -iv "Using a password on the command line interface can be insecure." < "$RSYSLOG_DYNNAME.mysqlerr"
+}
+
+# cleanup any temp data from mysql test
+# if we do not do this, we may run out of disk space
+# especially in container environment.
+mysql_cleanup_test() {
+ mysql --user=rsyslog --password=testbench -e "drop database $RSYSLOG_DYNNAME;" \
+ 2>&1 | grep -iv "Using a password on the command line interface can be insecure."
+}
+
+
+start_redis() {
+ check_command_available redis-server
+
+ export REDIS_DYN_CONF="${RSYSLOG_DYNNAME}.redis.conf"
+ export REDIS_DYN_DIR="$(pwd)/${RSYSLOG_DYNNAME}-redis"
+
+ # Only set a random port if not set (useful when Redis must be restarted during a test)
+ if [ -z "$REDIS_RANDOM_PORT" ]; then
+ export REDIS_RANDOM_PORT="$(get_free_port)"
+ fi
+
+ cp $srcdir/testsuites/redis.conf $REDIS_DYN_CONF
+ mkdir -p $REDIS_DYN_DIR
+
+ sed -itemp "s+<tmpdir>+${REDIS_DYN_DIR}+g" $REDIS_DYN_CONF
+ sed -itemp "s+<rndport>+${REDIS_RANDOM_PORT}+g" $REDIS_DYN_CONF
+
+ # Start the server
+ echo "Starting redis with conf file $REDIS_DYN_CONF"
+ redis-server $REDIS_DYN_CONF &
+ $TESTTOOL_DIR/msleep 2000
+
+ # Wait for Redis to be fully up
+ timeoutend=10
+ until nc -w1 -z 127.0.0.1 $REDIS_RANDOM_PORT; do
+ echo "Waiting for Redis to start..."
+ $TESTTOOL_DIR/msleep 1000
+ (( timeseconds=timeseconds + 2 ))
+
+ if [ "$timeseconds" -gt "$timeoutend" ]; then
+ echo "--- TIMEOUT ( $timeseconds ) reached!!!"
+ if [ ! -d ${REDIS_DYN_DIR}/redis.log ]; then
+ echo "no Redis logs"
+ else
+ echo "Dumping ${REDIS_DYN_DIR}/redis.log"
+ echo "========================================="
+ cat ${REDIS_DYN_DIR}/redis.log
+ echo "========================================="
+ fi
+ error_exit 1
+ fi
+ done
+}
+
+cleanup_redis() {
+ if [ -d ${REDIS_DYN_DIR} ]; then
+ rm -rf ${REDIS_DYN_DIR}
+ fi
+ if [ -f ${REDIS_DYN_CONF} ]; then
+ rm -f ${REDIS_DYN_CONF}
+ fi
+}
+
+stop_redis() {
+ if [ -f "$REDIS_DYN_DIR/redis.pid" ]; then
+ redispid=$(cat $REDIS_DYN_DIR/redis.pid)
+ echo "Stopping Redis instance"
+ kill $redispid
+
+ i=0
+
+ # Check if redis instance went down!
+ while [ -f $REDIS_DYN_DIR/redis.pid ]; do
+ redispid=$(cat $REDIS_DYN_DIR/redis.pid)
+ if [[ "" != "$redispid" ]]; then
+ $TESTTOOL_DIR/msleep 100 # wait 100 milliseconds
+ if test $i -gt $TB_TIMEOUT_STARTSTOP; then
+ echo "redis server (PID $redispid) still running - Performing hard shutdown (-9)"
+ kill -9 $redispid
+ break
+ fi
+ (( i++ ))
+ else
+ # Break the loop
+ break
+ fi
+ done
+ fi
+}
+
+redis_command() {
+ check_command_available redis-cli
+
+ if [ -z "$1" ]; then
+ echo "redis_command: no command provided!"
+ error_exit 1
+ fi
+
+ printf "$1\n" | redis-cli -p "$REDIS_RANDOM_PORT"
+}
+
+# $1 - replacement string
+# $2 - start search string
+# $3 - file name
+# $4 - expected value
+first_column_sum_check() {
+ sum=$(grep "$2" < "$3" | sed -e "$1" | awk '{s+=$1} END {print s}')
+ if [ "x${sum}" != "x$4" ]; then
+ printf '\n============================================================\n'
+ echo FAIL: sum of first column with edit-expr "'$1'" run over lines from file "'$3'" matched by "'$2'" equals "'$sum'" which is NOT equal to EXPECTED value of "'$4'"
+ echo "file contents:"
+ cat $3
+ error_exit 1
+ fi
+}
+
+#
+# Helper functions to start/stop python snmp trap receiver
+#
+snmp_start_trapreceiver() {
+ # Args: 1=port 2=outputfilename
+ # Args 2 and up are passed along as is to snmptrapreceiver.py
+ snmptrapreceiver=$srcdir/snmptrapreceiver.py
+ if [ ! -f ${snmptrapreceiver} ]; then
+ echo "Cannot find ${snmptrapreceiver} for omsnmp test"
+ error_exit 1
+ fi
+
+ if [ "x$1" == "x" ]; then
+ snmp_server_port="10162"
+ else
+ snmp_server_port="$1"
+ fi
+
+ if [ "x$2" == "x" ]; then
+ output_file="${RSYSLOG_DYNNAME}.snmp.out"
+ else
+ output_file="$2"
+ fi
+
+ # Create work directory for parallel tests
+ snmp_work_dir=${RSYSLOG_DYNNAME}/snmptrapreceiver
+
+ snmp_server_pidfile="${snmp_work_dir}/snmp_server.pid"
+ snmp_server_logfile="${snmp_work_dir}/snmp_server.log"
+ mkdir -p ${snmp_work_dir}
+
+ server_args="${snmp_server_port} 127.0.0.1 ${output_file}"
+
+ $PYTHON ${snmptrapreceiver} ${server_args} ${snmp_server_logfile} >> ${snmp_server_logfile} 2>&1 &
+ if [ ! $? -eq 0 ]; then
+ echo "Failed to start snmptrapreceiver."
+ rm -rf ${snmp_work_dir}
+ error_exit 1
+ fi
+
+ snmp_server_pid=$!
+ echo ${snmp_server_pid} > ${snmp_server_pidfile}
+
+ while test ! -s "${snmp_server_logfile}"; do
+ $TESTTOOL_DIR/msleep 100 # wait 100 milliseconds
+ if [ $(date +%s) -gt $(( TB_STARTTEST + TB_TEST_MAX_RUNTIME )) ]; then
+ printf '%s ABORT! Timeout waiting on startup (pid file %s)\n' "$(tb_timestamp)" "$1"
+ ls -l "$1"
+ ps -fp $(cat "$1")
+ snmp_stop_trapreceiver
+ error_exit 1
+# else
+# echo "waiting...${snmp_server_logfile}..."
+ fi
+ done
+
+ echo "Started snmptrapreceiver with args ${server_args} with pid ${snmp_server_pid}"
+}
+
+snmp_stop_trapreceiver() {
+ # Args: None
+ snmp_work_dir=${RSYSLOG_DYNNAME}/snmptrapreceiver
+ if [ ! -d ${snmp_work_dir} ]; then
+ echo "snmptrapreceiver server ${snmp_work_dir} does not exist, no action needed"
+ else
+ echo "Stopping snmptrapreceiver server"
+ kill -9 $(cat ${snmp_work_dir}/snmp_server.pid) > /dev/null 2>&1
+ # Done at testexit already!: rm -rf ${snmp_work_dir}
+ fi
+}
+
+wait_for_stats_flush() {
+ echo "will wait for stats push"
+ emitmsg=0
+ while [[ ! -f $1 ]]; do
+ if [ $((++emitmsg % 10)) == 0 ]; then
+ echo waiting for stats file "'$1'" to be created
+ fi
+ $TESTTOOL_DIR/msleep 100
+ done
+ prev_count=$(grep -c 'BEGIN$' <$1)
+ new_count=$prev_count
+ start_loop="$(date +%s)"
+ emit_waiting=0
+ while [[ "x$prev_count" == "x$new_count" ]]; do
+ # busy spin, because it allows as close timing-coordination
+ # in actual test run as possible
+ if [ $(date +%s) -gt $(( TB_STARTTEST + TB_TEST_MAX_RUNTIME )) ]; then
+ printf '%s ABORT! Timeout waiting on stats push\n' "$(tb_timestamp)" "$1"
+ error_exit 1
+ else
+ # waiting for 1000 is heuristically "sufficiently but not too
+ # frequent" enough
+ if [ $((++emit_waiting)) == 1000 ]; then
+ printf 'still waiting for stats push...\n'
+ emit_waiting=0
+ fi
+ fi
+ new_count=$(grep -c 'BEGIN$' <"$1")
+ done
+ echo "stats push registered"
+}
+
+# Check file exists and is of a particular size
+# $1 - file to check
+# $2 - size to check
+file_size_check() {
+ local size=$(ls -l $1 | awk {'print $5'})
+ if [ "${size}" != "${2}" ]; then
+ printf 'File:[%s] has unexpected size. Expected:[%d], Size:[%d]\n', $1 $2 $size
+ error_exit 1
+ fi
+ return 0
+}
+
+case $1 in
+ 'init') $srcdir/killrsyslog.sh # kill rsyslogd if it runs for some reason
+ source set-envvars
+ # for (solaris) load debugging, uncomment next 2 lines:
+ #export LD_DEBUG=all
+ #ldd ../tools/rsyslogd
+
+ # environment debug
+ #find / -name "librelp.so*"
+ #ps -ef |grep syslog
+ #netstat -a | grep LISTEN
+
+ # cleanup of hanging instances from previous runs
+ # practice has shown this is pretty useful!
+ #for pid in $(ps -eo pid,args|grep '/tools/[r]syslogd ' |sed -e 's/\( *\)\([0-9]*\).*/\2/');
+ #do
+ #echo "ERROR: left-over previous instance $pid, killing it"
+ #ps -fp $pid
+ #pwd
+ #kill -9 $pid
+ #done
+ # end cleanup
+
+ # some default names (later to be set in other parts, once we support fully
+ # parallel tests)
+ export RSYSLOG_DFLT_LOG_INTERNAL=1 # testbench needs internal messages logged internally!
+ if [ -f testbench_test_failed_rsyslog ] && [ "$ABORT_ALL_ON_TEST_FAIL" == "YES" ]; then
+ echo NOT RUNNING TEST as previous test $(cat testbench_test_failed_rsyslog) failed.
+ exit 77
+ fi
+ if [ "$RSYSLOG_DYNNAME" != "" ]; then
+ echo "FAIL: \$RSYSLOG_DYNNAME already set in init"
+ echo "hint: was init accidentally called twice?"
+ exit 2
+ fi
+ export RSYSLOG_DYNNAME="rstb_$(./test_id $(basename $0))$(tr -dc 'a-zA-Z0-9' < /dev/urandom | head --bytes 4)"
+ export RSYSLOG_OUT_LOG="${RSYSLOG_DYNNAME}.out.log"
+ export RSYSLOG2_OUT_LOG="${RSYSLOG_DYNNAME}_2.out.log"
+ export RSYSLOG_PIDBASE="${RSYSLOG_DYNNAME}:" # also used by instance 2!
+ #export IMDIAG_PORT=13500 DELETE ME
+ #export IMDIAG_PORT2=13501 DELETE ME
+ #export TCPFLOOD_PORT=13514 DELETE ME
+
+ # Extra Variables for Test statistic reporting
+ export RSYSLOG_TESTNAME=$(basename $0)
+
+ # we create one file with the test name, so that we know what was
+ # left over if "make distcheck" complains
+ touch $RSYSLOG_DYNNAME-$(basename $0).test_id
+
+ if [ -z $RS_SORTCMD ]; then
+ RS_SORTCMD="sort"
+ fi
+ if [ -z $RS_SORT_NUMERIC_OPT ]; then
+ if [ "$(uname)" == "AIX" ]; then
+ RS_SORT_NUMERIC_OPT=-n
+ else
+ RS_SORT_NUMERIC_OPT=-g
+ fi
+ fi
+ if [ -z $RS_CMPCMD ]; then
+ RS_CMPCMD="cmp"
+ fi
+ if [ -z $RS_HEADCMD ]; then
+ RS_HEADCMD="head"
+ fi
+ # we assume TZ is set, else most test will fail. So let's ensure
+ # this really is the case
+ if [ -z $TZ ]; then
+ echo "testbench: TZ env var not set, setting it to UTC"
+ export TZ=UTC
+ fi
+ ulimit -c unlimited &> /dev/null # at least try to get core dumps
+ export TB_STARTTEST=$(date +%s)
+ printf '%s\n' '------------------------------------------------------------'
+ printf '%s Test: %s\n' "$(tb_timestamp)" "$0"
+ printf '%s\n' '------------------------------------------------------------'
+ rm -f xlate*.lkp_tbl
+ rm -f log log* # RSyslog debug output
+ rm -f work
+ rm -rf test-logdir stat-file1
+ rm -f rsyslog.empty imfile-state:* omkafka-failed.data
+ rm -f tmp.qi nocert
+ rm -f core.* vgcore.* core*
+ # Note: rsyslog.action.*.include must NOT be deleted, as it
+ # is used to setup some parameters BEFORE calling init. This
+ # happens in chained test scripts. Delete on exit is fine,
+ # though.
+ # note: TCPFLOOD_EXTRA_OPTS MUST NOT be unset in init, because
+ # some tests need to set it BEFORE calling init to accommodate
+ # their generic test drivers.
+ if [ "$TCPFLOOD_EXTRA_OPTS" != '' ] ; then
+ echo TCPFLOOD_EXTRA_OPTS set: $TCPFLOOD_EXTRA_OPTS
+ fi
+ if [ "$USE_AUTO_DEBUG" != 'on' ] ; then
+ rm -f IN_AUTO_DEBUG
+ fi
+ if [ -e IN_AUTO_DEBUG ]; then
+ export valgrind="valgrind --malloc-fill=ff --free-fill=fe --suppressions=$srcdir/known_issues.supp ${EXTRA_VALGRIND_SUPPRESSIONS:-} --log-fd=1"
+ fi
+ ;;
+
+ 'check-ipv6-available') # check if IPv6 - will exit 77 when not OK
+ if ip address > /dev/null ; then
+ cmd="ip address"
+ else
+ cmd="ifconfig -a"
+ fi
+ echo command used for ipv6 detection: $cmd
+ $cmd | grep ::1 > /dev/null
+ if [ $? -ne 0 ] ; then
+ printf 'this test requires an active IPv6 stack, which we do not have here\n'
+ error_exit 77
+ fi
+ ;;
+ 'kill-immediate') # kill rsyslog unconditionally
+ kill -9 $(cat $RSYSLOG_PIDBASE.pid)
+ # note: we do not wait for the actual termination!
+ ;;
+ 'ensure-no-process-exists')
+ ps -ef | grep -v grep | grep -qF "$2"
+ if [ "x$?" == "x0" ]; then
+ echo "assertion failed: process with name-fragment matching '$2' found"
+ error_exit 1
+ fi
+ ;;
+ 'grep-check') # grep for "$EXPECTED" present in rsyslog.log - env var must be set
+ # before this method is called
+ grep "$EXPECTED" ${RSYSLOG_OUT_LOG} > /dev/null
+ if [ $? -eq 1 ]; then
+ echo "GREP FAIL: ${RSYSLOG_OUT_LOG} content:"
+ cat ${RSYSLOG_OUT_LOG}
+ echo "GREP FAIL: expected text not found:"
+ echo "$EXPECTED"
+ error_exit 1
+ fi;
+ ;;
+ 'block-stats-flush')
+ echo blocking stats flush
+ echo "blockStatsReporting" | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+ ;;
+ 'await-stats-flush-after-block')
+ echo unblocking stats flush and waiting for it
+ echo "awaitStatsReport" | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+ ;;
+ 'allow-single-stats-flush-after-block-and-wait-for-it')
+ echo blocking stats flush
+ echo "awaitStatsReport block_again" | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+ ;;
+ 'wait-for-dyn-stats-reset')
+ echo "will wait for dyn-stats-reset"
+ while [[ ! -f $2 ]]; do
+ echo waiting for stats file "'$2'" to be created
+ $TESTTOOL_DIR/msleep 100
+ done
+ prev_purged=$(grep -F 'origin=dynstats' < $2 | grep -F "${3}.purge_triggered=" | sed -e 's/.\+.purge_triggered=//g' | awk '{s+=$1} END {print s}')
+ new_purged=$prev_purged
+ while [[ "x$prev_purged" == "x$new_purged" ]]; do
+ new_purged=$(grep -F 'origin=dynstats' < "$2" | grep -F "${3}.purge_triggered=" | sed -e 's/.\+\.purge_triggered=//g' | awk '{s+=$1} END {print s}') # busy spin, because it allows as close timing-coordination in actual test run as possible
+ $TESTTOOL_DIR/msleep 10
+ done
+ echo "dyn-stats reset for bucket ${3} registered"
+ ;;
+ 'assert-first-column-sum-greater-than')
+ sum=$(grep $3 <$4| sed -e $2 | awk '{s+=$1} END {print s}')
+ if [ ! $sum -gt $5 ]; then
+ echo sum of first column with edit-expr "'$2'" run over lines from file "'$4'" matched by "'$3'" equals "'$sum'" which is smaller than expected lower-limit of "'$5'"
+ echo "file contents:"
+ cat $4
+ error_exit 1
+ fi
+ ;;
+ 'content-pattern-check')
+ grep -q "$2" < ${RSYSLOG_OUT_LOG}
+ if [ "$?" -ne "0" ]; then
+ echo content-check failed, not every line matched pattern "'$2'"
+ echo "file contents:"
+ cat -n $4
+ error_exit 1
+ fi
+ ;;
+ 'require-journalctl') # check if journalctl exists on the system
+ if ! hash journalctl 2>/dev/null ; then
+ echo "journalctl command missing, skipping test"
+ exit 77
+ fi
+ ;;
+ 'check-inotify') # Check for inotify/fen support
+ if [ -n "$(find /usr/include -name 'inotify.h' -print -quit)" ]; then
+ echo [inotify mode]
+ elif [ -n "$(find /usr/include/sys/ -name 'port.h' -print -quit)" ]; then
+ grep -qF "PORT_SOURCE_FILE" < /usr/include/sys/port.h
+ if [ "$?" -ne "0" ]; then
+ echo [port.h found but FEN API not implemented , skipping...]
+ exit 77 # FEN API not available, skip this test
+ fi
+ echo [fen mode]
+ else
+ echo [inotify/fen not supported, skipping...]
+ exit 77 # no inotify available, skip this test
+ fi
+ ;;
+ 'check-inotify-only') # Check for ONLY inotify support
+ if [ -n "$(find /usr/include -name 'inotify.h' -print -quit)" ]; then
+ echo [inotify mode]
+ else
+ echo [inotify not supported, skipping...]
+ exit 77 # no inotify available, skip this test
+ fi
+ ;;
+ *) echo "TESTBENCH error: invalid argument" $1
+ exit 100
+esac
diff --git a/tests/diagtalker.c b/tests/diagtalker.c
new file mode 100644
index 0000000..4414618
--- /dev/null
+++ b/tests/diagtalker.c
@@ -0,0 +1,165 @@
+/* A yet very simple tool to talk to imdiag (this replaces the
+ * previous Java implementation in order to get fewer dependencies).
+ *
+ * Copyright 2010-2018 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>
+#if defined(__FreeBSD__)
+#include <netinet/in.h>
+#endif
+
+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, "[%d] connect() failed\n", port);
+ exit(1);
+ } else {
+ fprintf(stderr, "[%d] connect failed, retrying...\n", port);
+ usleep(100000); /* ms = 1000 us! */
+ }
+ }
+ }
+ if(retries > 0) {
+ fprintf(stderr, "[%d] connection established.\n", port);
+ }
+
+ *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[%d]: %s", targetPort, line);
+ if (strstr(line, "imdiag::error") != NULL) {
+ exit(1);
+ }
+ }
+}
+
+
+/* Run the test.
+ * rgerhards, 2009-04-03
+ */
+int main(int argc, char *argv[])
+{
+ int ret = 0;
+ int opt;
+
+ while((opt = getopt(argc, argv, "t:p:")) != -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/dircreate_dflt.sh b/tests/dircreate_dflt.sh
new file mode 100755
index 0000000..758e5fa
--- /dev/null
+++ b/tests/dircreate_dflt.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Test for automatic creation of dynafile directories
+# note that we use the "'${RSYSLOG_DYNNAME}'.spool" directory, because it is handled by diag.sh
+# in any case, so we do not need to add any extra new test dir.
+# added 2009-11-30 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# set spool locations and switch queue to disk-only mode
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+$MainMsgQueueFilename mainq
+$MainMsgQueueType disk
+
+$template dynfile,"'$RSYSLOG_DYNNAME'.logdir/'$RSYSLOG_OUT_LOG'"
+*.* ?dynfile
+'
+startup
+injectmsg 0 1 # a single message is sufficient
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+if [ ! -e $RSYSLOG_DYNNAME.logdir/$RSYSLOG_OUT_LOG ]
+then
+ echo "$RSYSLOG_DYNNAME.logdir or logfile not created!"
+ error_exit 1
+fi
+exit_test
diff --git a/tests/dircreate_off.sh b/tests/dircreate_off.sh
new file mode 100755
index 0000000..bcd6d1a
--- /dev/null
+++ b/tests/dircreate_off.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Test for automatic creation of dynafile directories
+# note that we use the ${RSYSLOG_DYNNAME}.spool directory, because it is handled by diag.sh
+# in any case, so we do not need to add any extra new test dir.
+# added 2009-11-30 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# set spool locations and switch queue to disk-only mode
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+$MainMsgQueueFilename mainq
+$MainMsgQueueType disk
+
+$CreateDirs off
+$template dynfile,'$RSYSLOG_DYNNAME'.OUT_LOG
+*.* ?dynfile
+'
+startup
+injectmsg 0 1 # a single message is sufficient
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+if [ -e $RSYSLOG_DYNNAME.logdir/$RSYSLOG_OUT_LOG ]
+then
+ echo "$RSYSLOG_DYNNAME.logdir or logfile WAS created where not permitted to!"
+ error-exit 1
+fi
+exit_test
diff --git a/tests/discard-allmark-vg.sh b/tests/discard-allmark-vg.sh
new file mode 100755
index 0000000..2f42a8d
--- /dev/null
+++ b/tests/discard-allmark-vg.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[discard-allmark.sh\]: testing discard-allmark functionality
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$ActionWriteAllMarkMessages on
+
+:msg, contains, "00000001" ~
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup_vg
+tcpflood -m10 -i1
+# we need to give rsyslog a little time to settle the receiver
+./msleep 1500
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown_vg
+check_exit_vg
+seq_check 2 10
+exit_test
diff --git a/tests/discard-allmark.sh b/tests/discard-allmark.sh
new file mode 100755
index 0000000..c965a54
--- /dev/null
+++ b/tests/discard-allmark.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo \[discard-allmark.sh\]: testing discard-allmark functionality
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$ActionWriteAllMarkMessages on
+
+:msg, contains, "00000001" ~
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+tcpflood -m10 -i1
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 2 10
+exit_test
diff --git a/tests/discard-rptdmsg-vg.sh b/tests/discard-rptdmsg-vg.sh
new file mode 100755
index 0000000..16733fc
--- /dev/null
+++ b/tests/discard-rptdmsg-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/discard-rptdmsg.sh
diff --git a/tests/discard-rptdmsg.sh b/tests/discard-rptdmsg.sh
new file mode 100755
index 0000000..6c56891
--- /dev/null
+++ b/tests/discard-rptdmsg.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# testing discard-rptdmsg functionality when no repeated message is present
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+$RepeatedMsgReduction on
+
+:msg, contains, "00000001" ~
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+tcpflood -m10 -i1
+shutdown_when_empty
+wait_shutdown
+seq_check 2 10
+exit_test
diff --git a/tests/discard.sh b/tests/discard.sh
new file mode 100755
index 0000000..64827ea
--- /dev/null
+++ b/tests/discard.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# Test for discard functionality
+# This test checks if discard works. It is not a perfect test but
+# will find at least segfaults and obviously not discarded messages.
+# added 2009-07-30 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+# uncomment for debugging support:
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10
+generate_conf
+add_conf '
+:msg, contains, "00000000" ~
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check 1 $((NUMMESSAGES-1))
+exit_test
diff --git a/tests/diskq-rfc5424.sh b/tests/diskq-rfc5424.sh
new file mode 100755
index 0000000..6ba40ce
--- /dev/null
+++ b/tests/diskq-rfc5424.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# detect queue corruption based on invalid property bag ordering.
+# Note: this mimics an issue actually seen in practice.
+# Triggering condition: "json" property (message variables) are present
+# and "structured-data" property is also present. Caused rsyslog to
+# thrash the queue file, getting messages stuck in it and loosing all
+# after the initial problem occurrence.
+# add 2017-02-08 by Rainer Gerhards, released under ASL 2.0
+
+uname
+if [ $(uname) = "SunOS" ] ; then
+ echo "This test currently does not work on all flavors of Solaris."
+ exit 77
+fi
+
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="rs")
+
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+ruleset(name="rs2" queue.type="disk" queue.filename="rs2_q"
+ queue.spoolDirectory="'${RSYSLOG_DYNNAME}'.spool") {
+ set $!tmp=$msg;
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+ruleset(name="rs") {
+ set $!tmp=$msg;
+ call rs2
+}
+'
+startup
+tcpflood -m$NUMMESSAGES -y
+shutdown_when_empty
+wait_shutdown
+seq_check
+
+exit_test
diff --git a/tests/diskqueue-fail.sh b/tests/diskqueue-fail.sh
new file mode 100755
index 0000000..a8c63b2
--- /dev/null
+++ b/tests/diskqueue-fail.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# checks that nothing bad happens if a DA (disk) queue runs out
+# of configured disk space
+# addd 2017-02-07 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100
+generate_conf
+add_conf '
+module( load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="queuefail")
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+
+ruleset(
+ name="queuefail"
+ queue.type="Disk"
+ queue.filename="fssailstocreate"
+ queue.maxDiskSpace="4m"
+ queue.maxfilesize="1m"
+ queue.timeoutenqueue="300000"
+ queue.lowwatermark="5000"
+) {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+startup
+
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES
+
+shutdown_when_empty
+wait_shutdown
+seq_check
+
+exit_test
diff --git a/tests/diskqueue-fsync.sh b/tests/diskqueue-fsync.sh
new file mode 100755
index 0000000..a0dece2
--- /dev/null
+++ b/tests/diskqueue-fsync.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# Test for disk-only queue mode (with fsync for queue files)
+# This test checks if queue files can be correctly written
+# and read back, but it does not test the transition from
+# memory to disk mode for DA queues.
+# added 2009-06-09 by Rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+# uncomment for debugging support:
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000 # 1000 messages should be enough - the disk fsync test is very slow!
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+if [ $(uname) = "SunOS" ] ; then
+ echo "This test currently does not work on all flavors of Solaris."
+ exit 77
+fi
+
+generate_conf
+add_conf '
+# set spool locations and switch queue to disk-only mode
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+$MainMsgQueueSyncQueueFiles on
+$MainMsgQueueTimeoutShutdown 10000
+$MainMsgQueueFilename mainq
+$MainMsgQueueType disk
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/diskqueue-full.sh b/tests/diskqueue-full.sh
new file mode 100755
index 0000000..85db1a3
--- /dev/null
+++ b/tests/diskqueue-full.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# checks that nothing bad happens if a DA (disk) queue runs out
+# of configured disk space
+# addd 2017-02-07 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+generate_conf
+add_conf '
+module(load="../plugins/omtesting/.libs/omtesting")
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+main_queue(queue.filename="mainq" queue.maxDiskSpace="4m"
+ queue.maxfilesize="1m"
+ queue.timeoutenqueue="300000"
+ queue.lowwatermark="5000"
+)
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+
+:omtesting:sleep 0 5000
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+injectmsg 0 20000
+ls -l ${RSYSLOG_DYNNAME}.spool
+shutdown_when_empty
+wait_shutdown
+ls -l ${RSYSLOG_DYNNAME}.spool
+seq_check 0 19999
+
+exit_test
diff --git a/tests/diskqueue-multithread-es.sh b/tests/diskqueue-multithread-es.sh
new file mode 100755
index 0000000..a4901c3
--- /dev/null
+++ b/tests/diskqueue-multithread-es.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# This test stresses the DA queue disk subsystem with multiple threads.
+# To do so, the in-memory queues are deliberately sized very small.
+# NOTE: depending on circumstances, this test frequently starts the
+# DAWorkerPool, which shuffles messages over from the main queue to
+# the DA queue. It terminates when we reach low water mark. This can
+# happen in our test. So the DA worker pool thread is, depending on
+# timing, started and shut down multiple times. This is not a problem
+# indication!
+# The pstats display is for manual review - it helps to see how many
+# messages actually went to the DA queue.
+# Copyright (C) 2019-10-28 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+. ${srcdir:=.}/diag.sh init
+export ES_PORT=19200
+export NUMMESSAGES=25000
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+ensure_elasticsearch_ready
+generate_conf
+add_conf '
+global(workDirectory="'$RSYSLOG_DYNNAME'.spool")
+template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+main_queue(queue.size="2000")
+module(load="../plugins/impstats/.libs/impstats"
+ log.syslog="off" log.file="'$RSYSLOG_DYNNAME'.pstats" interval="1")
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+:msg, contains, "msgnum:" {
+ action(type="omelasticsearch" name="act-es"
+ template="tpl" server="127.0.0.1"
+ serverport="'$ES_PORT'"
+ searchIndex="rsyslog_testbench"
+ bulkmode="on"
+ queue.lowwatermark="250"
+ queue.highwatermark="1500"
+ queue.type="linkedList" queue.size="2000"
+ queue.dequeueBatchSize="64" queue.workerThreads="4"
+ queue.fileName="actq" queue.workerThreadMinimumMessages="64")
+}
+'
+startup
+tcpflood -m$NUMMESSAGES # use tcpflood to get better async processing than injectmsg!
+shutdown_when_empty
+wait_shutdown
+echo FOR MANUAL REVIEW: pstats
+tail $RSYSLOG_DYNNAME.pstats | grep maxqsize
+es_getdata $NUMMESSAGES $ES_PORT
+seq_check
+exit_test
diff --git a/tests/diskqueue-non-unique-prefix.sh b/tests/diskqueue-non-unique-prefix.sh
new file mode 100755
index 0000000..f11da27
--- /dev/null
+++ b/tests/diskqueue-non-unique-prefix.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# Test for config parser to check that disk queue file names are
+# unique.
+# added 2019-05-02 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+if 0 then {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.notused"
+ queue.filename="qf1" queue.type="linkedList")
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.notused"
+ queue.filename="qf1" queue.type="linkedList")
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.notused"
+ queue.filename="qf2" queue.type="linkedList")
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.notused"
+ queue.spooldirectory="'$RSYSLOG_DYNNAME'.spool2"
+ queue.filename="qf2" queue.type="linkedList")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "and file name prefix 'qf1' already used"
+check_not_present "and file name prefix 'qf2' already used"
+exit_test
diff --git a/tests/diskqueue.sh b/tests/diskqueue.sh
new file mode 100755
index 0000000..d7868f2
--- /dev/null
+++ b/tests/diskqueue.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# Test for disk-only queue mode
+# This test checks if queue files can be correctly written
+# and read back, but it does not test the transition from
+# memory to disk mode for DA queues.
+# added 2009-04-17 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=20000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+# set spool locations and switch queue to disk-only mode
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+$MainMsgQueueFilename mainq
+$MainMsgQueueType disk
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+if ($msg contains "msgnum:") then
+ ?dynfile;outfmt
+else
+ action(type="omfile" file="'$RSYSLOG_DYNNAME.syslog.log'")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+check_not_present "spool.* open error" $RSYSLOG_DYNNAME.syslog.log
+exit_test
diff --git a/tests/dnscache-TTL-0-vg.sh b/tests/dnscache-TTL-0-vg.sh
new file mode 100755
index 0000000..8618bd1
--- /dev/null
+++ b/tests/dnscache-TTL-0-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# added 2019-04-12 by Rainer Gerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/dnscache-TTL-0.sh
diff --git a/tests/dnscache-TTL-0.sh b/tests/dnscache-TTL-0.sh
new file mode 100755
index 0000000..3d169d0
--- /dev/null
+++ b/tests/dnscache-TTL-0.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# addd 2019-04-12 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=20 # should be sufficient to stress DNS cache
+generate_conf
+add_conf '
+global(reverselookup.cache.ttl.default="0"
+ reverselookup.cache.ttl.enable="on")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+tcpflood -m$NUMMESSAGES -c10 # run on 10 connections --> 10 dns cache calls
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/dynfile_invalid2.sh b/tests/dynfile_invalid2.sh
new file mode 100755
index 0000000..73de5db
--- /dev/null
+++ b/tests/dynfile_invalid2.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# This test checks if omfile segfaults when a file open() in dynacache mode fails.
+# The test is mimiced after a real-life scenario (which, of course, was much more
+# complex).
+#
+# added 2010-03-22 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:3%\n"
+$template dynfile,"%msg:F,58:2%.log" # complete name is in message
+$OMFileFlushOnTXEnd off
+$DynaFileCacheSize 4
+$omfileFlushInterval 1
+local0.* ?dynfile;outfmt
+'
+startup
+# we send handcrafted message. We have a dynafile cache of 4, and now send one message
+# each to fill up the cache.
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:0\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:1\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:2\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:3\""
+# the next one has caused a segfault in practice
+# note that /proc/rsyslog.error.file must not be creatable
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:/proc/rsyslog.error.file:boom\""
+# some more writes
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:4\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:5\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:6\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:7\""
+# done message generation
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+cat $RSYSLOG_DYNNAME.out.*.log > $RSYSLOG_OUT_LOG
+seq_check 0 7
+exit_test
diff --git a/tests/dynfile_invld_async.sh b/tests/dynfile_invld_async.sh
new file mode 100755
index 0000000..a96ae44
--- /dev/null
+++ b/tests/dynfile_invld_async.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# This test checks if omfile segfaults when a file open() in dynacache mode fails.
+# The test is mimiced after a real-life scenario (which, of course, was much more
+# complex).
+#
+# added 2010-03-09 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:3%\n"
+$template dynfile,"%msg:F,58:2%.log" # complete name is in message
+$OMFileFlushOnTXEnd on
+$OMFileAsyncWriting on
+$DynaFileCacheSize 4
+local0.* ?dynfile;outfmt
+'
+startup
+# we send handcrafted message. We have a dynafile cache of 4, and now send one message
+# each to fill up the cache.
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:0\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:1\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:2\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:3\""
+# the next one has caused a segfault in practice
+# note that /proc/rsyslog.error.file must not be creatable
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:/proc/rsyslog.error.file:boom\""
+# some more writes
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:4\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:5\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:6\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:7\""
+# done message generation
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+cat $RSYSLOG_DYNNAME.out.*.log > $RSYSLOG_OUT_LOG
+seq_check 0 7
+exit_test
diff --git a/tests/dynfile_invld_sync.sh b/tests/dynfile_invld_sync.sh
new file mode 100755
index 0000000..5bb1f3c
--- /dev/null
+++ b/tests/dynfile_invld_sync.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# This test checks if omfile segfaults when a file open() in dynacache mode fails.
+# The test is mimiced after a real-life scenario (which, of course, was much more
+# complex).
+#
+# added 2010-03-09 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:3%\n"
+$template dynfile,"%msg:F,58:2%.log" # complete name is in message
+$OMFileFlushOnTXEnd on
+$OMFileAsyncWriting off
+$DynaFileCacheSize 4
+local0.* ?dynfile;outfmt
+'
+startup
+# we send handcrafted message. We have a dynafile cache of 4, and now send one message
+# each to fill up the cache.
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:0\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:1\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:2\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:3\""
+# the next one has caused a segfault in practice
+# note that /proc/rsyslog.error.file must not be creatable
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:/proc/rsyslog.error.file:boom\""
+# some more writes
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:4\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:5\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:6\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:7\""
+# done message generation
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+cat $RSYSLOG_DYNNAME.out.*.log > $RSYSLOG_OUT_LOG
+seq_check 0 7
+exit_test
diff --git a/tests/dynstats-json-vg.sh b/tests/dynstats-json-vg.sh
new file mode 100755
index 0000000..8a80543
--- /dev/null
+++ b/tests/dynstats-json-vg.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# added 2016-03-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[dynstats-json-vg.sh\]: test for verifying stats are reported correctly in json format with valgrind
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+dyn_stats(name="stats_one")
+dyn_stats(name="stats_two")
+
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="2" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="json")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+set $.p = field($msg, 32, 1);
+if ($.p == "foo") then {
+ set $.ign = dyn_inc("stats_one", $.p);
+ set $.ign = dyn_inc("stats_two", $.p);
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+wait_queueempty
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+custom_content_check '{ "name": "global", "origin": "dynstats", "values": { "stats_one.ops_overflow": 0, "stats_one.new_metric_add": 1, "stats_one.no_metric": 0, "stats_one.metrics_purged": 0, "stats_one.ops_ignored": 0, "stats_one.purge_triggered": 0, "stats_two.ops_overflow": 0, "stats_two.new_metric_add": 1, "stats_two.no_metric": 0, "stats_two.metrics_purged": 0, "stats_two.ops_ignored": 0, "stats_two.purge_triggered": 0 } }' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check '{ "name": "stats_one", "origin": "dynstats.bucket", "values": { "foo": 1 } }' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check '{ "name": "stats_two", "origin": "dynstats.bucket", "values": { "foo": 1 } }' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/dynstats-json.sh b/tests/dynstats-json.sh
new file mode 100755
index 0000000..ba11cdd
--- /dev/null
+++ b/tests/dynstats-json.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# added 2016-03-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[dynstats-json.sh\]: test for verifying stats are reported correctly in json format
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+dyn_stats(name="stats_one")
+dyn_stats(name="stats_two")
+
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="2" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="json")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+set $.p = field($msg, 32, 1);
+if ($.p == "foo") then {
+ set $.ign = dyn_inc("stats_one", $.p);
+ set $.ign = dyn_inc("stats_two", $.p);
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+wait_queueempty
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+custom_content_check '{ "name": "global", "origin": "dynstats", "values": { "stats_one.ops_overflow": 0, "stats_one.new_metric_add": 1, "stats_one.no_metric": 0, "stats_one.metrics_purged": 0, "stats_one.ops_ignored": 0, "stats_one.purge_triggered": 0, "stats_two.ops_overflow": 0, "stats_two.new_metric_add": 1, "stats_two.no_metric": 0, "stats_two.metrics_purged": 0, "stats_two.ops_ignored": 0, "stats_two.purge_triggered": 0 } }' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check '{ "name": "stats_one", "origin": "dynstats.bucket", "values": { "foo": 1 } }' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check '{ "name": "stats_two", "origin": "dynstats.bucket", "values": { "foo": 1 } }' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/dynstats-vg.sh b/tests/dynstats-vg.sh
new file mode 100755
index 0000000..9a0ff8b
--- /dev/null
+++ b/tests/dynstats-vg.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# added 2015-11-13 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[dynstats-vg.sh\]: test for gathering stats over dynamic metric names with valgrind
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on")
+
+template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n")
+
+dyn_stats(name="msg_stats")
+
+set $.msg_prefix = field($msg, 32, 1);
+
+set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+injectmsg_file $srcdir/testsuites/dynstats_input
+wait_queueempty
+content_check "foo 001 0"
+content_check "bar 002 0"
+content_check "baz 003 0"
+content_check "foo 004 0"
+content_check "baz 005 0"
+content_check "foo 006 0"
+rst_msleep 1100 # wait for stats flush
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+custom_content_check 'bar=1' "${RSYSLOG_DYNNAME}.out.stats.log"
+first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+exit_test
diff --git a/tests/dynstats.sh b/tests/dynstats.sh
new file mode 100755
index 0000000..51a016f
--- /dev/null
+++ b/tests/dynstats.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# added 2015-11-10 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on")
+
+template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n")
+
+dyn_stats(name="msg_stats")
+
+set $.msg_prefix = field($msg, 32, 1);
+
+set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+injectmsg_file $srcdir/testsuites/dynstats_input
+wait_queueempty
+content_check "foo 001 0"
+content_check "bar 002 0"
+content_check "baz 003 0"
+content_check "foo 004 0"
+content_check "baz 005 0"
+content_check "foo 006 0"
+rst_msleep 1100 # wait for stats flush
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+custom_content_check 'bar=1' "${RSYSLOG_DYNNAME}.out.stats.log"
+first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+exit_test
diff --git a/tests/dynstats_ctr_reset.sh b/tests/dynstats_ctr_reset.sh
new file mode 100755
index 0000000..17e9519
--- /dev/null
+++ b/tests/dynstats_ctr_reset.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# added 2015-11-16 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo \[dynstats_ctr_reset.sh\]: test to ensure correctness of stats-ctr reset
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+dyn_stats(name="msg_stats_resettable_on" resettable="on")
+dyn_stats(name="msg_stats_resettable_off" resettable="off")
+dyn_stats(name="msg_stats_resettable_default")
+
+set $.msg_prefix = field($msg, 32, 1);
+
+set $.x = dyn_inc("msg_stats_resettable_on", $.msg_prefix);
+set $.y = dyn_inc("msg_stats_resettable_off", $.msg_prefix);
+set $.z = dyn_inc("msg_stats_resettable_default", $.msg_prefix);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+injectmsg_file $srcdir/testsuites/dynstats_input_2
+wait_queueempty
+sleep 1
+injectmsg_file $srcdir/testsuites/dynstats_input_3
+wait_queueempty
+sleep 1
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "foo 006"
+custom_content_check 'bar=1' "${RSYSLOG_DYNNAME}.out.stats.log"
+first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'msg_stats_resettable_on.*foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'msg_stats_resettable_on.*bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'msg_stats_resettable_on.*baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+. $srcdir/diag.sh assert-first-column-sum-greater-than 's/.*foo=\([0-9]*\)/\1/g' 'msg_stats_resettable_off.*foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+. $srcdir/diag.sh assert-first-column-sum-greater-than 's/.*bar=\([0-9]*\)/\1/g' 'msg_stats_resettable_off.*bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+. $srcdir/diag.sh assert-first-column-sum-greater-than 's/.*baz=\([0-9]*\)/\1/g' 'msg_stats_resettable_off.*baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'msg_stats_resettable_default.*foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'msg_stats_resettable_default.*bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'msg_stats_resettable_default.*baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+exit_test
diff --git a/tests/dynstats_nometric.sh b/tests/dynstats_nometric.sh
new file mode 100755
index 0000000..fef6cda
--- /dev/null
+++ b/tests/dynstats_nometric.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# added 2015-11-17 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[dynstats_nometric.sh\]: test for dyn-stats meta-metric behavior with zero-length metric name
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on")
+
+template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n")
+
+dyn_stats(name="msg_stats")
+
+set $.msg_prefix = field($msg, 32, 2);
+
+set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+wait_queueempty
+rm $srcdir/${RSYSLOG_DYNNAME}.out.stats.log
+issue_HUP #reopen stats file
+injectmsg_file $srcdir/testsuites/dynstats_empty_input
+wait_queueempty
+rst_msleep 1100 # wait for stats flush
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+first_column_sum_check 's/.*no_metric=//g' 'no_metric=' "${RSYSLOG_DYNNAME}.out.stats.log" 5
+custom_assert_content_missing 'foo' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing 'bar' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing 'baz' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing 'corge' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check 'quux=1' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check 'grault=1' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/dynstats_overflow-vg.sh b/tests/dynstats_overflow-vg.sh
new file mode 100755
index 0000000..90e377c
--- /dev/null
+++ b/tests/dynstats_overflow-vg.sh
@@ -0,0 +1,102 @@
+#!/bin/bash
+# added 2015-11-13 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[dynstats_overflow-vg.sh\]: test for gathering stats when metrics exceed provisioned capacity
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="2" severity="7" resetCounters="on" Ruleset="stats" bracketing="on")
+
+template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n")
+
+dyn_stats(name="msg_stats" unusedMetricLife="1" maxCardinality="3")
+
+set $.msg_prefix = field($msg, 32, 1);
+
+if (re_match($.msg_prefix, "foo|bar|baz|quux|corge|grault")) then {
+ set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix);
+} else {
+ set $.increment_successful = -1;
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+. $srcdir/diag.sh block-stats-flush
+injectmsg_file $srcdir/testsuites/dynstats_input_more_0
+injectmsg_file $srcdir/testsuites/dynstats_input_more_1
+wait_queueempty
+. $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it
+
+first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 5
+first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+
+custom_assert_content_missing 'quux' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing 'corge' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing 'grault' "${RSYSLOG_DYNNAME}.out.stats.log"
+
+first_column_sum_check 's/.*new_metric_add=\([0-9]*\)/\1/g' 'new_metric_add=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*ops_overflow=\([0-9]*\)/\1/g' 'ops_overflow=' "${RSYSLOG_DYNNAME}.out.stats.log" 5
+first_column_sum_check 's/.*no_metric=\([0-9]*\)/\1/g' 'no_metric=' "${RSYSLOG_DYNNAME}.out.stats.log" 0
+
+#ttl-expiry(2*ttl in worst case, ttl + delta in best) so metric-names reset should have happened
+. $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it
+. $srcdir/diag.sh await-stats-flush-after-block
+
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+
+first_column_sum_check 's/.*metrics_purged=\([0-9]*\)/\1/g' 'metrics_purged=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+
+rm ${RSYSLOG_DYNNAME}.out.stats.log
+issue_HUP #reopen stats file
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+. $srcdir/diag.sh block-stats-flush
+injectmsg_file $srcdir/testsuites/dynstats_input_more_2
+wait_queueempty
+. $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it
+
+content_check "foo 001 0"
+content_check "bar 002 0"
+content_check "baz 003 0"
+content_check "foo 004 0"
+content_check "baz 005 0"
+content_check "foo 006 0"
+content_check "quux 007 -6"
+content_check "corge 008 -6"
+content_check "quux 009 -6"
+content_check "foo 010 0"
+content_check "corge 011 -6"
+content_check "grault 012 -6"
+content_check "foo 013 0"
+content_check "corge 014 0"
+content_check "grault 015 0"
+content_check "quux 016 0"
+content_check "foo 017 -6"
+content_check "corge 018 0"
+
+first_column_sum_check 's/.*corge=\([0-9]*\)/\1/g' 'corge=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+first_column_sum_check 's/.*grault=\([0-9]*\)/\1/g' 'grault=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*quux=\([0-9]*\)/\1/g' 'quux=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+
+first_column_sum_check 's/.*new_metric_add=\([0-9]*\)/\1/g' 'new_metric_add=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*ops_overflow=\([0-9]*\)/\1/g' 'ops_overflow=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*no_metric=\([0-9]*\)/\1/g' 'no_metric=' "${RSYSLOG_DYNNAME}.out.stats.log" 0
+
+. $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it
+. $srcdir/diag.sh await-stats-flush-after-block
+
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+first_column_sum_check 's/.*metrics_purged=\([0-9]*\)/\1/g' 'metrics_purged=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+
+custom_assert_content_missing 'foo' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/dynstats_overflow.sh b/tests/dynstats_overflow.sh
new file mode 100755
index 0000000..b63d812
--- /dev/null
+++ b/tests/dynstats_overflow.sh
@@ -0,0 +1,102 @@
+#!/bin/bash
+# added 2015-11-13 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="2" severity="7" resetCounters="on" Ruleset="stats" bracketing="on")
+
+template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n")
+
+dyn_stats(name="msg_stats" unusedMetricLife="1" maxCardinality="3")
+
+set $.msg_prefix = field($msg, 32, 1);
+
+if (re_match($.msg_prefix, "foo|bar|baz|quux|corge|grault")) then {
+ set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix);
+} else {
+ set $.increment_successful = -1;
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+. $srcdir/diag.sh block-stats-flush
+injectmsg_file $srcdir/testsuites/dynstats_input_more_0
+injectmsg_file $srcdir/testsuites/dynstats_input_more_1
+wait_queueempty
+. $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it
+
+#first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 5
+first_column_sum_check 's/.*foo=//g' 'foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 5
+first_column_sum_check 's/.*bar=//g' 'bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*baz=//g' 'baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+
+custom_assert_content_missing 'quux' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing 'corge' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing 'grault' "${RSYSLOG_DYNNAME}.out.stats.log"
+
+first_column_sum_check 's/.*new_metric_add=//g' 'new_metric_add=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*ops_overflow=//g' 'ops_overflow=' "${RSYSLOG_DYNNAME}.out.stats.log" 5
+first_column_sum_check 's/.*no_metric=//g' 'no_metric=' "${RSYSLOG_DYNNAME}.out.stats.log" 0
+
+#ttl-expiry(2*ttl in worst case, ttl + delta in best) so metric-names reset should have happened
+. $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it
+. $srcdir/diag.sh await-stats-flush-after-block
+
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+
+first_column_sum_check 's/.*metrics_purged=//g' 'metrics_purged=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+
+rm ${RSYSLOG_DYNNAME}.out.stats.log
+issue_HUP #reopen stats file
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+. $srcdir/diag.sh block-stats-flush
+injectmsg_file $srcdir/testsuites/dynstats_input_more_2
+wait_queueempty
+. $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it
+
+content_check "foo 001 0"
+content_check "bar 002 0"
+content_check "baz 003 0"
+content_check "foo 004 0"
+content_check "baz 005 0"
+content_check "foo 006 0"
+content_check "quux 007 -6"
+content_check "corge 008 -6"
+content_check "quux 009 -6"
+content_check "foo 010 0"
+content_check "corge 011 -6"
+content_check "grault 012 -6"
+content_check "foo 013 0"
+content_check "corge 014 0"
+content_check "grault 015 0"
+content_check "quux 016 0"
+content_check "foo 017 -6"
+content_check "corge 018 0"
+
+first_column_sum_check 's/.*corge=//g' 'corge=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+first_column_sum_check 's/.*grault=//g' 'grault=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*quux=//g' 'quux=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+
+first_column_sum_check 's/.*new_metric_add=//g' 'new_metric_add=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*ops_overflow=//g' 'ops_overflow=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*no_metric=//g' 'no_metric=' "${RSYSLOG_DYNNAME}.out.stats.log" 0
+
+. $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it
+. $srcdir/diag.sh await-stats-flush-after-block
+
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+
+first_column_sum_check 's/.*metrics_purged=//g' 'metrics_purged=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+
+custom_assert_content_missing 'foo' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/dynstats_prevent_premature_eviction-vg.sh b/tests/dynstats_prevent_premature_eviction-vg.sh
new file mode 100755
index 0000000..c61927a
--- /dev/null
+++ b/tests/dynstats_prevent_premature_eviction-vg.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+# added 2016-04-13 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[dynstats_prevent_premature_eviction-vg.sh\]: test for ensuring metrics are not evicted before unused-ttl with valgrind
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="4" severity="7" resetCounters="on" Ruleset="stats" bracketing="on")
+
+template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n")
+
+dyn_stats(name="msg_stats" unusedMetricLife="1" resettable="off")
+
+set $.msg_prefix = field($msg, 32, 1);
+
+if (re_match($.msg_prefix, "foo|bar|baz|quux|corge|grault")) then {
+ set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix);
+} else {
+ set $.increment_successful = -1;
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+. $srcdir/diag.sh block-stats-flush
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+. $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it
+injectmsg_file $srcdir/testsuites/dynstats_input_2
+. $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it
+injectmsg_file $srcdir/testsuites/dynstats_input_3
+. $srcdir/diag.sh await-stats-flush-after-block
+wait_queueempty
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+content_check "foo 001 0"
+content_check "foo 006 0"
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+ # because dyn-accumulators for existing metrics were posted-to under a second, they should not have been evicted
+custom_content_check 'baz=2' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check 'bar=1' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check 'foo=3' "${RSYSLOG_DYNNAME}.out.stats.log"
+# sum is high because accumulators were never reset, and we expect them to last specific number of cycles(when we posted before ttl expiry)
+first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 6
+first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*new_metric_add=\([0-9]*\)/\1/g' 'new_metric_add=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*ops_overflow=\([0-9]*\)/\1/g' 'ops_overflow=' "${RSYSLOG_DYNNAME}.out.stats.log" 0
+first_column_sum_check 's/.*no_metric=\([0-9]*\)/\1/g' 'no_metric=' "${RSYSLOG_DYNNAME}.out.stats.log" 0
+exit_test
diff --git a/tests/dynstats_prevent_premature_eviction.sh b/tests/dynstats_prevent_premature_eviction.sh
new file mode 100755
index 0000000..f86eb43
--- /dev/null
+++ b/tests/dynstats_prevent_premature_eviction.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# test for ensuring metrics are not evicted before unused-ttl
+# added 2016-04-13 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="4" severity="7" resetCounters="on" Ruleset="stats" bracketing="on")
+
+template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n")
+
+dyn_stats(name="msg_stats" unusedMetricLife="1" resettable="off")
+
+set $.msg_prefix = field($msg, 32, 1);
+
+if (re_match($.msg_prefix, "foo|bar|baz|quux|corge|grault")) then {
+ set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix);
+} else {
+ set $.increment_successful = -1;
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+rst_msleep 1000
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+rst_msleep 4000
+injectmsg_file $srcdir/testsuites/dynstats_input_2
+rst_msleep 4000
+injectmsg_file $srcdir/testsuites/dynstats_input_3
+wait_queueempty
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+content_check "foo 001 0"
+content_check "foo 006 0"
+shutdown_when_empty
+wait_shutdown
+# because dyn-accumulators for existing metrics were posted-to under a second, they should not have been evicted
+custom_content_check 'baz=2' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check 'bar=1' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check 'foo=3' "${RSYSLOG_DYNNAME}.out.stats.log"
+# sum is high because accumulators were never reset, and we expect them to last specific number of cycles(when we posted before ttl expiry)
+first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 6
+first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*new_metric_add=\([0-9]*\)/\1/g' 'new_metric_add=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*ops_overflow=\([0-9]*\)/\1/g' 'ops_overflow=' "${RSYSLOG_DYNNAME}.out.stats.log" 0
+first_column_sum_check 's/.*no_metric=\([0-9]*\)/\1/g' 'no_metric=' "${RSYSLOG_DYNNAME}.out.stats.log" 0
+exit_test
diff --git a/tests/dynstats_reset-vg.sh b/tests/dynstats_reset-vg.sh
new file mode 100755
index 0000000..06060b6
--- /dev/null
+++ b/tests/dynstats_reset-vg.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# added 2015-11-13 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[dynstats_reset-vg.sh\]: test for gathering stats with a known-dyn-metrics reset in-between
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="4" severity="7" resetCounters="on" Ruleset="stats" bracketing="on")
+
+template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n")
+
+dyn_stats(name="msg_stats" unusedMetricLife="1" resettable="off")
+
+set $.msg_prefix = field($msg, 32, 1);
+
+if (re_match($.msg_prefix, "foo|bar|baz|quux|corge|grault")) then {
+ set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix);
+} else {
+ set $.increment_successful = -1;
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+rst_msleep 8100 #two seconds for unused-metrics to be kept under observation, another two them to be cleared off
+injectmsg_file $srcdir/testsuites/dynstats_input_2
+rst_msleep 8100
+injectmsg_file $srcdir/testsuites/dynstats_input_3
+rst_msleep 8100
+wait_queueempty
+content_check "foo 001 0"
+content_check "bar 002 0"
+content_check "baz 003 0"
+content_check "foo 004 0"
+content_check "baz 005 0"
+content_check "foo 006 0"
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+ # because dyn-metrics would be reset before it can accumulate and report high counts, sleep between msg-injection ensures that
+custom_assert_content_missing 'baz=2' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing 'foo=2' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing 'foo=3' "${RSYSLOG_DYNNAME}.out.stats.log"
+# but actual reported stats (aggregate) should match
+first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+exit_test
diff --git a/tests/dynstats_reset.sh b/tests/dynstats_reset.sh
new file mode 100755
index 0000000..30e47d2
--- /dev/null
+++ b/tests/dynstats_reset.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# added 2015-11-13 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="4" severity="7" resetCounters="on" Ruleset="stats" bracketing="on")
+
+template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n")
+
+dyn_stats(name="msg_stats" unusedMetricLife="1" resettable="off")
+
+set $.msg_prefix = field($msg, 32, 1);
+
+if (re_match($.msg_prefix, "foo|bar|baz|quux|corge|grault")) then {
+ set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix);
+} else {
+ set $.increment_successful = -1;
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+injectmsg_file "$srcdir/testsuites/dynstats_input_1"
+rst_msleep 8100
+injectmsg_file "$srcdir/testsuites/dynstats_input_2"
+rst_msleep 8100
+injectmsg_file "$srcdir/testsuites/dynstats_input_3"
+rst_msleep 8100
+wait_queueempty
+content_check "foo 001 0"
+content_check "bar 002 0"
+content_check "baz 003 0"
+content_check "foo 004 0"
+content_check "baz 005 0"
+content_check "foo 006 0"
+shutdown_when_empty
+wait_shutdown
+ # because dyn-metrics would be reset before it can accumulate and report high counts, sleep between msg-injection ensures that
+custom_assert_content_missing 'baz=2' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing 'foo=2' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing 'foo=3' "${RSYSLOG_DYNNAME}.out.stats.log"
+# but actual reported stats (aggregate) should match
+first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'foo=' ${RSYSLOG_DYNNAME}.out.stats.log 3
+first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'bar=' ${RSYSLOG_DYNNAME}.out.stats.log 1
+first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'baz=' ${RSYSLOG_DYNNAME}.out.stats.log 2
+first_column_sum_check 's/.*new_metric_add=\([0-9]*\)/\1/g' 'new_metric_add=' "${RSYSLOG_DYNNAME}.out.stats.log" 6
+first_column_sum_check 's/.*ops_overflow=\([0-9]*\)/\1/g' 'ops_overflow=' "${RSYSLOG_DYNNAME}.out.stats.log" 0
+first_column_sum_check 's/.*no_metric=\([0-9]*\)/\1/g' 'no_metric=' "${RSYSLOG_DYNNAME}.out.stats.log" 0
+first_column_sum_check 's/.*metrics_purged=\([0-9]*\)/\1/g' 'metrics_purged=' "${RSYSLOG_DYNNAME}.out.stats.log" 6
+exit_test
diff --git a/tests/dynstats_reset_without_pstats_reset.sh b/tests/dynstats_reset_without_pstats_reset.sh
new file mode 100755
index 0000000..13e69e9
--- /dev/null
+++ b/tests/dynstats_reset_without_pstats_reset.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# test to ensure correctness of stats-ctr reset when pstats reset is turned off
+# added 2015-11-16 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="off" Ruleset="stats" bracketing="on")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+dyn_stats(name="msg_stats_resettable_on" resettable="on")
+dyn_stats(name="msg_stats_resettable_off" resettable="off")
+dyn_stats(name="msg_stats_resettable_default")
+
+set $.msg_prefix = field($msg, 32, 1);
+
+set $.x = dyn_inc("msg_stats_resettable_on", $.msg_prefix);
+set $.y = dyn_inc("msg_stats_resettable_off", $.msg_prefix);
+set $.z = dyn_inc("msg_stats_resettable_default", $.msg_prefix);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+injectmsg_file $srcdir/testsuites/dynstats_input_2
+wait_queueempty
+sleep 1
+injectmsg_file $srcdir/testsuites/dynstats_input_3
+wait_queueempty
+sleep 1
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "foo 006"
+custom_content_check 'foo=3' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check 'bar=1' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check 'baz=2' "${RSYSLOG_DYNNAME}.out.stats.log"
+first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'msg_stats_resettable_on.*foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'msg_stats_resettable_on.*bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'msg_stats_resettable_on.*baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+. $srcdir/diag.sh assert-first-column-sum-greater-than 's/.*foo=\([0-9]*\)/\1/g' 'msg_stats_resettable_off.*foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+. $srcdir/diag.sh assert-first-column-sum-greater-than 's/.*bar=\([0-9]*\)/\1/g' 'msg_stats_resettable_off.*bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+. $srcdir/diag.sh assert-first-column-sum-greater-than 's/.*baz=\([0-9]*\)/\1/g' 'msg_stats_resettable_off.*baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'msg_stats_resettable_default.*foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3
+first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'msg_stats_resettable_default.*bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1
+first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'msg_stats_resettable_default.*baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2
+exit_test
diff --git a/tests/elasticsearch-error-format-check.py b/tests/elasticsearch-error-format-check.py
new file mode 100644
index 0000000..f8f091d
--- /dev/null
+++ b/tests/elasticsearch-error-format-check.py
@@ -0,0 +1,137 @@
+import json
+import sys
+import os
+def checkDefaultErrorFile():
+ with open(os.environ['RSYSLOG_DYNNAME'] + ".errorfile") as json_file:
+ json_data = json.load(json_file)
+ indexCount =0
+ replyCount=0
+ for item in json_data:
+ if item == "request":
+ for reqItem in json_data[item]:
+ if reqItem == "url":
+ print("url found")
+ print(reqItem)
+ elif reqItem == "postdata":
+ print("postdata found")
+ indexCount = str(json_data[item]).count('\"_index\":')
+ print(reqItem)
+ else:
+ print(reqItem)
+ print("Unknown item found")
+ sys.exit(1)
+
+ elif item == "reply":
+ for replyItem in json_data[item]:
+ if replyItem == "items":
+ print(json_data[item][replyItem])
+ replyCount = str(json_data[item][replyItem]).count('_index')
+ elif replyItem == "errors":
+ print("error node found")
+ elif replyItem == "took":
+ print("took node found")
+ else:
+ print(replyItem)
+ print("Unknown item found")
+ sys.exit(3)
+
+ else:
+ print(item)
+ print("Unknown item found")
+ print("error")
+ sys.exit(4)
+ if replyCount == indexCount :
+ return 0
+ else:
+ sys.exit(7)
+ return 0
+
+
+def checkErrorOnlyFile():
+ with open(os.environ['RSYSLOG_DYNNAME'] + ".errorfile") as json_file:
+ json_data = json.load(json_file)
+ indexCount =0
+ replyCount=0
+ for item in json_data:
+ if item == "request":
+ print(json_data[item])
+ indexCount = str(json_data[item]).count('\"_index\":')
+
+
+ elif item == "url":
+ print("url found")
+
+
+ elif item == "reply":
+ print(json_data[item])
+ replyCount = str(json_data[item]).count('\"_index\":')
+
+ else:
+ print(item)
+ print("Unknown item found")
+ print("error")
+ sys.exit(4)
+ if replyCount == indexCount :
+ return 0
+ else:
+ sys.exit(7)
+ return 0
+
+def checkErrorInterleaved():
+ with open(os.environ['RSYSLOG_DYNNAME'] + ".errorfile") as json_file:
+ json_data = json.load(json_file)
+ indexCount =0
+ replyCount=0
+ for item in json_data:
+ print(item)
+ if item == "response":
+ for responseItem in json_data[item]:
+ print(responseItem)
+ for res in responseItem:
+ print(res)
+ if res == "request":
+ print(responseItem[res])
+ indexCount = str(responseItem[res]).count('\"_index\":')
+ print("request count ", indexCount)
+ elif res == "reply":
+ print(responseItem[res])
+ replyCount = str(responseItem[res]).count('\"_index\":')
+ print("reply count ", replyCount)
+ else:
+ print(res)
+ print("Unknown item found")
+ sys.exit(9)
+ if replyCount != indexCount :
+ sys.exit(8)
+
+
+
+ elif item == "url":
+ print("url found")
+
+
+
+
+ else:
+ print(item)
+ print("Unknown item found")
+ sys.exit(4)
+
+ return 0
+
+def checkInterleaved():
+ return checkErrorInterleaved()
+
+if __name__ == "__main__":
+ option = sys.argv[1]
+ if option == "default":
+ checkDefaultErrorFile()
+ elif option == "erroronly":
+ checkErrorOnlyFile()
+ elif option == "errorinterleaved":
+ checkErrorInterleaved()
+ elif option == "interleaved":
+ checkErrorInterleaved()
+ else:
+ print("Usage: <script> <default|erroronly|errorinterleaved>")
+ sys.exit(6)
diff --git a/tests/elasticsearch-stop.sh b/tests/elasticsearch-stop.sh
new file mode 100755
index 0000000..1029431
--- /dev/null
+++ b/tests/elasticsearch-stop.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+# This is not a real test, but a script to stop ElasticSearch when all tests
+# are done (or for manual testing).
+# Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+cleanup_elasticsearch
+exit_test
diff --git a/tests/empty-app-name.sh b/tests/empty-app-name.sh
new file mode 100755
index 0000000..1b07c2e
--- /dev/null
+++ b/tests/empty-app-name.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# addd 2019-12-27 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+global(parser.PermitSlashInProgramname="off")
+
+template(name="outfmt" type="string" string="%syslogtag%,%programname%,%app-name%\n")
+local0.* action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+tcpflood -m 1 -M "\"<133>Aug 6 16:57:54 host /no-app-name msgh ...x\""
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="/no-app-name,,-"
+cmp_exact
+exit_test
diff --git a/tests/empty-hostname.sh b/tests/empty-hostname.sh
new file mode 100755
index 0000000..e083368
--- /dev/null
+++ b/tests/empty-hostname.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This tests checks for a anomaly we have seen in practice:
+# gethostname() may return an empty string as hostname (""). This broke
+# some versions of rsyslog, newer ones return "localhost" in that case.
+# The test is done with the help of a preload library specifically written
+# for this purpose (liboverride_gethostname.so). It will override
+# gethostname() and return an empty string. Then, the test checks if the
+# hardcoded default of "localhost-empty-hostname" is used.
+# Note that the test may fail if the library is not properly preloaded.
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "AIX" "we cannot preload required dummy lib"
+generate_conf
+add_conf '
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+export RSYSLOG_PRELOAD=.libs/liboverride_gethostname.so
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+grep " localhost-empty-hostname " < $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "expected hostname \"localhost-empty-hostname\" not found in logs, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/empty-prop-comparison.sh b/tests/empty-prop-comparison.sh
new file mode 100755
index 0000000..7d703cc
--- /dev/null
+++ b/tests/empty-prop-comparison.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# addd 2016-07-08 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+set $!doOutput = "";
+if $msg contains "msgnum:0" then
+ set $!doOutput = "1";
+
+if $!doOutput == "" then stop
+action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+echo '<167>Mar 6 16:57:54 172.20.245.8 test: msgnum:0
+<167>Mar 6 16:57:54 172.20.245.8 test: msgnum:' > $RSYSLOG_DYNNAME.input
+tcpflood -B -I $RSYSLOG_DYNNAME.input
+shutdown_when_empty
+wait_shutdown
+seq_check 0 0
+exit_test
diff --git a/tests/empty-ruleset.sh b/tests/empty-ruleset.sh
new file mode 100755
index 0000000..4e258d7
--- /dev/null
+++ b/tests/empty-ruleset.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Copyright 2014-11-20 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+custom_wait_file_lines() {
+ wait_file_lines "$RSYSLOG_OUT_LOG" 10000
+}
+export QUEUE_EMPTY_CHECK_FUNC=custom_wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+$MainMsgQueueTimeoutShutdown 10000
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="real")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port2" ruleset="empty")
+
+$template outfmt,"%msg:F,58:2%\n"
+
+ruleset(name="empty") {
+}
+
+ruleset(name="real") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+startup
+assign_tcpflood_port2 "${RSYSLOG_DYNNAME}.tcpflood_port2"
+tcpflood -p$TCPFLOOD_PORT2 -m5000 -i0 # these should NOT show up
+tcpflood -p$TCPFLOOD_PORT -m10000 -i5000
+tcpflood -p$TCPFLOOD_PORT2 -m500 -i15000 # these should NOT show up
+shutdown_when_empty
+wait_shutdown
+seq_check 5000 14999
+exit_test
diff --git a/tests/err1.rstest b/tests/err1.rstest
new file mode 100644
index 0000000..8c56887
--- /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/es-basic-bulk-vg.sh b/tests/es-basic-bulk-vg.sh
new file mode 100755
index 0000000..ab41f3f
--- /dev/null
+++ b/tests/es-basic-bulk-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/es-basic-bulk.sh
diff --git a/tests/es-basic-bulk.sh b/tests/es-basic-bulk.sh
new file mode 100755
index 0000000..d9935cd
--- /dev/null
+++ b/tests/es-basic-bulk.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_PORT=19200
+export NUMMESSAGES=10000
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+ensure_elasticsearch_ready
+
+init_elasticsearch
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+:msg, contains, "msgnum:" {
+ action(type="omelasticsearch"
+ template="tpl"
+ serverport=`echo $ES_PORT`
+ searchIndex="rsyslog_testbench"
+ bulkmode="on")
+}
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+es_getdata $NUMMESSAGES $ES_PORT
+seq_check
+exit_test
diff --git a/tests/es-basic-errfile-empty.sh b/tests/es-basic-errfile-empty.sh
new file mode 100755
index 0000000..92fb99c
--- /dev/null
+++ b/tests/es-basic-errfile-empty.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+export ES_PORT=19200
+export NUMMESSAGES=1500 # slow test, thus low number - large number is NOT necessary
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+ensure_elasticsearch_ready
+
+init_elasticsearch
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+:msg, contains, "msgnum:" action(type="omelasticsearch"
+ template="tpl"
+ serverport=`echo $ES_PORT`
+ searchIndex="rsyslog_testbench"
+ errorFile="./'${RSYSLOG_DYNNAME}.errorfile'")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+es_getdata
+if [ -f ${RSYSLOG_DYNNAME}.errorfile ]
+then
+ echo "error: error file exists!"
+ error_exit 1
+fi
+seq_check
+exit_test
diff --git a/tests/es-basic-errfile-popul.sh b/tests/es-basic-errfile-popul.sh
new file mode 100755
index 0000000..c85ef83
--- /dev/null
+++ b/tests/es-basic-errfile-popul.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+export ES_PORT=19200
+export NUMMESSAGES=1000 # slow test, thus low number - large number is NOT necessary
+ensure_elasticsearch_ready
+
+init_elasticsearch
+curl -H 'Content-Type: application/json' -XPUT localhost:19200/rsyslog_testbench/ -d '{
+ "mappings": {
+ "test-type": {
+ "properties": {
+ "msgnum": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+}'
+generate_conf
+add_conf '
+# Note: we must mess up with the template, because we can not
+# instruct ES to put further constraints on the data type and
+# values. So we require integer and make sure it is none.
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"x%msg:F,58:2%\"}")
+
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+:msg, contains, "msgnum:" action(type="omelasticsearch"
+ template="tpl"
+ searchIndex="rsyslog_testbench"
+ searchType="test-type"
+ serverport="19200"
+ bulkmode="off"
+ errorFile="./'${RSYSLOG_DYNNAME}'.errorfile")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+if [ ! -f ${RSYSLOG_DYNNAME}.errorfile ]
+then
+ echo "error: error file does not exist!"
+ error_exit 1
+fi
+exit_test
diff --git a/tests/es-basic-es6.0.sh b/tests/es-basic-es6.0.sh
new file mode 100755
index 0000000..bfcdbbf
--- /dev/null
+++ b/tests/es-basic-es6.0.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+export ES_PORT=19200
+export NUMMESSAGES=2000 # slow test
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+ensure_elasticsearch_ready
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+
+if $msg contains "msgnum:" then
+ action(type="omelasticsearch"
+ server="127.0.0.1"
+ serverport="19200"
+ template="tpl"
+ searchIndex="rsyslog_testbench")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+es_getdata
+seq_check
+exit_test
diff --git a/tests/es-basic-es7.14.sh b/tests/es-basic-es7.14.sh
new file mode 100755
index 0000000..744ce68
--- /dev/null
+++ b/tests/es-basic-es7.14.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-7.14.1-linux-x86_64.tar.gz
+export ES_PORT=19200
+export NUMMESSAGES=2000 # slow test
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+ensure_elasticsearch_ready
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+
+if $msg contains "msgnum:" then
+ action(type="omelasticsearch"
+ server="127.0.0.1"
+ serverport="19200"
+ template="tpl"
+ searchIndex="rsyslog_testbench")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+es_getdata
+seq_check
+exit_test
diff --git a/tests/es-basic-ha-vg.sh b/tests/es-basic-ha-vg.sh
new file mode 100755
index 0000000..60899ee
--- /dev/null
+++ b/tests/es-basic-ha-vg.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+export ES_PORT=19200
+ensure_elasticsearch_ready
+
+init_elasticsearch
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+:msg, contains, "msgnum:" action(type="omelasticsearch"
+ template="tpl"
+ serverport=`echo $ES_PORT`
+ searchIndex="rsyslog_testbench"
+ bulkmode="on")
+'
+startup_vg
+injectmsg
+wait_queueempty
+shutdown_when_empty
+wait_shutdown_vg
+es_getdata $NUMMESSAGES $ES_PORT
+seq_check
+exit_test
diff --git a/tests/es-basic-ha.sh b/tests/es-basic-ha.sh
new file mode 100755
index 0000000..f676771
--- /dev/null
+++ b/tests/es-basic-ha.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+ensure_elasticsearch_ready
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+module(load="../plugins/impstats/.libs/impstats" interval="2" severity="7" resetCounters="off" Ruleset="stats" bracketing="on" format="json")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+:msg, contains, "msgnum:" action(type="omelasticsearch"
+ server=["localhost", "http://localhost/", "localhost:9201"]
+ serverport="19200"
+ template="tpl"
+ searchIndex="rsyslog_testbench")
+'
+startup
+injectmsg 0 100
+wait_queueempty
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+shutdown_when_empty
+wait_shutdown
+es_getdata 100 19200
+seq_check 0 99
+# The configuration makes every other request from message #3 fail checkConn (N/2-1)
+custom_content_check '"failed.checkConn": 49' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/es-basic-server.sh b/tests/es-basic-server.sh
new file mode 100755
index 0000000..176e4d4
--- /dev/null
+++ b/tests/es-basic-server.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_PORT=19200
+export NUMMESSAGES=1500 # slow test, thus low number - large number is NOT necessary
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+ensure_elasticsearch_ready
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+:msg, contains, "msgnum:" action(type="omelasticsearch"
+ server="localhost"
+ serverport=`echo $ES_PORT`
+ template="tpl"
+ searchIndex="rsyslog_testbench")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+es_getdata
+seq_check
+exit_test
diff --git a/tests/es-basic-vg.sh b/tests/es-basic-vg.sh
new file mode 100755
index 0000000..bb273c3
--- /dev/null
+++ b/tests/es-basic-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/es-basic.sh
diff --git a/tests/es-basic-vgthread.sh b/tests/es-basic-vgthread.sh
new file mode 100755
index 0000000..3c42fc2
--- /dev/null
+++ b/tests/es-basic-vgthread.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_PORT=19200
+export NUMMESSAGES=5000 # test is pretty slow, so use a low number
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+ensure_elasticsearch_ready
+
+init_elasticsearch
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+
+if $msg contains "msgnum:" then {
+ action(type="omelasticsearch"
+ server="127.0.0.1"
+ serverport=`echo $ES_PORT`
+ template="tpl"
+ searchIndex="rsyslog_testbench")
+}
+'
+startup_vgthread
+injectmsg
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+es_getdata
+seq_check
+exit_test
diff --git a/tests/es-basic.sh b/tests/es-basic.sh
new file mode 100755
index 0000000..92e7f64
--- /dev/null
+++ b/tests/es-basic.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_PORT=19200
+export NUMMESSAGES=1000 # 1000 is sufficient, as this test is pretty slow
+REBIND_INTERVAL=100 # should be enough to run several times for $NUMMESSAGES
+
+queue_empty_check() {
+ es_shutdown_empty_check && \
+ content_check --check-only --regex '"name": "omelasticsearch".*"submitted": '$NUMMESSAGES \
+ $RSYSLOG_DYNNAME.spool/omelasticsearch-stats.log
+}
+export QUEUE_EMPTY_CHECK_FUNC=queue_empty_check
+
+ensure_elasticsearch_ready
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/impstats/.libs/impstats" interval="1"
+ log.file="'"$RSYSLOG_DYNNAME.spool"'/omelasticsearch-stats.log" log.syslog="off" format="cee")
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+
+if $msg contains "msgnum:" then
+ action(type="omelasticsearch"
+ server="127.0.0.1"
+ serverport="'$ES_PORT'"
+ template="tpl"
+ searchIndex="rsyslog_testbench"
+ rebindinterval="'$REBIND_INTERVAL'")
+'
+startup
+injectmsg 0 $NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+
+es_getdata $NUMMESSAGES $ES_PORT
+seq_check 0 $(( NUMMESSAGES - 1 ))
+rc=0
+if [ -f ${RSYSLOG_DYNNAME}.spool/omelasticsearch-stats.log ] ; then
+ $PYTHON <${RSYSLOG_DYNNAME}.spool/omelasticsearch-stats.log -c '
+import sys,json
+nrecs = int(sys.argv[1])
+nrebinds = nrecs/int(sys.argv[2])-1
+expected = { "name": "omelasticsearch", "origin": "omelasticsearch", "submitted": nrecs,
+ "failed.http": 0, "failed.httprequests": 0, "failed.checkConn": 0, "failed.es": 0,
+ "response.success": 0, "response.bad": 0, "response.duplicate": 0, "response.badargument": 0,
+ "response.bulkrejection": 0, "response.other": 0, "rebinds": nrebinds }
+actual = {}
+for line in sys.stdin:
+ jstart = line.find("{")
+ if jstart >= 0:
+ hsh = json.loads(line[jstart:])
+ if hsh["origin"] == "omelasticsearch":
+ actual = hsh
+if not expected == actual:
+ sys.stderr.write("ERROR: expected stats not equal to actual stats\n")
+ sys.stderr.write("ERROR: expected {}\n".format(expected))
+ sys.stderr.write("ERROR: actual {}\n".format(actual))
+ sys.exit(1)
+' $NUMMESSAGES $REBIND_INTERVAL || { rc=$?; echo error: expected stats not found in ${RSYSLOG_DYNNAME}.spool/omelasticsearch-stats.log; }
+else
+ echo error: stats file ${RSYSLOG_DYNNAME}.spool/omelasticsearch-stats.log not found
+ rc=1
+fi
+
+if [ $rc != 0 ] ; then
+ error_exit 1
+else
+ exit_test
+fi
diff --git a/tests/es-bulk-errfile-empty.sh b/tests/es-bulk-errfile-empty.sh
new file mode 100755
index 0000000..0237e6b
--- /dev/null
+++ b/tests/es-bulk-errfile-empty.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+export ES_PORT=19200
+export NUMMESSAGES=10000
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+ensure_elasticsearch_ready
+
+init_elasticsearch
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+:msg, contains, "msgnum:" {
+ action(type="omelasticsearch"
+ template="tpl"
+ serverport=`echo $ES_PORT`
+ searchIndex="rsyslog_testbench"
+ bulkmode="on"
+ errorFile="./'${RSYSLOG_DYNNAME}'.errorfile")
+}
+'
+startup
+injectmsg 0 $NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+es_getdata $NUMMESSAGES $ES_PORT
+if [ -f ${RSYSLOG_DYNNAME}.errorfile ]; then
+ printf 'error: error file exists!\n'
+ cat -n ${RSYSLOG_DYNNAME}.errorfile
+ error_exit 1
+fi
+seq_check
+exit_test
diff --git a/tests/es-bulk-errfile-popul-def-format.sh b/tests/es-bulk-errfile-popul-def-format.sh
new file mode 100755
index 0000000..00cec88
--- /dev/null
+++ b/tests/es-bulk-errfile-popul-def-format.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+ensure_elasticsearch_ready
+
+init_elasticsearch
+echo '{ "name" : "foo" }
+{"name": bar"}
+{"name": "baz"}
+{"name": foz"}' > $RSYSLOG_DYNNAME.inESData.inputfile
+generate_conf
+add_conf '
+global(workDirectory="'$RSYSLOG_DYNNAME.spool'")
+# Note: we must mess up with the template, because we can not
+# instruct ES to put further constraints on the data type and
+# values. So we require integer and make sure it is none.
+template(name="tpl" type="list") {
+ constant(value="{\"")
+ property(name="$!key") constant(value="\":") property(name="$!obj")
+ constant(value="}")
+}
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+module(load="../plugins/imfile/.libs/imfile")
+ruleset(name="foo") {
+ set $!key = "my_obj";
+ set $!obj = $msg;
+ action(type="omelasticsearch"
+ template="tpl"
+ searchIndex="rsyslog_testbench"
+ serverport="19200"
+ searchType="test-type"
+ bulkmode="on"
+ errorFile="./'${RSYSLOG_DYNNAME}'.errorfile")
+}
+
+input(type="imfile" File="'$RSYSLOG_DYNNAME.'inESData.inputfile"
+ Tag="foo"
+ Severity="info"
+ ruleset="foo")'
+startup
+shutdown_when_empty
+wait_shutdown
+
+$PYTHON $srcdir/elasticsearch-error-format-check.py default
+if [ $? -ne 0 ]
+then
+ echo "error: Format for error file different! " $?
+ error_exit 1
+fi
+exit_test
diff --git a/tests/es-bulk-errfile-popul-def-interleaved.sh b/tests/es-bulk-errfile-popul-def-interleaved.sh
new file mode 100755
index 0000000..6c423bb
--- /dev/null
+++ b/tests/es-bulk-errfile-popul-def-interleaved.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+ensure_elasticsearch_ready
+
+init_elasticsearch
+echo '{ "name" : "foo" }
+{"name": bar"}
+{"name": "baz"}
+{"name": foz"}' > $RSYSLOG_DYNNAME.inESData.inputfile
+generate_conf
+add_conf '
+global(workDirectory="'$RSYSLOG_DYNNAME.spool'")
+# Note: we must mess up with the template, because we can not
+# instruct ES to put further constraints on the data type and
+# values. So we require integer and make sure it is none.
+template(name="tpl" type="list") {
+ constant(value="{\"")
+ property(name="$!key") constant(value="\":") property(name="$!obj")
+ constant(value="}")
+}
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+module(load="../plugins/imfile/.libs/imfile")
+ruleset(name="foo") {
+ set $!key = "my_obj";
+ set $!obj = $msg;
+ action(type="omelasticsearch"
+ template="tpl"
+ searchIndex="rsyslog_testbench"
+ searchType="test-type"
+ serverport="19200"
+ bulkmode="on"
+ errorFile="./'${RSYSLOG_DYNNAME}'.errorfile"
+ interleaved="on")
+}
+
+input(type="imfile" File="'$RSYSLOG_DYNNAME.'inESData.inputfile"
+ Tag="foo"
+ Severity="info"
+ ruleset="foo")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+$PYTHON $srcdir/elasticsearch-error-format-check.py interleaved
+
+if [ $? -ne 0 ]
+then
+ echo "error: Format for error file different! " $?
+ exit 1
+fi
+exit_test
diff --git a/tests/es-bulk-errfile-popul-erronly-interleaved.sh b/tests/es-bulk-errfile-popul-erronly-interleaved.sh
new file mode 100755
index 0000000..dd50b77
--- /dev/null
+++ b/tests/es-bulk-errfile-popul-erronly-interleaved.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+ensure_elasticsearch_ready
+
+init_elasticsearch
+echo '{ "name" : "foo" }
+{"name": bar"}
+{"name": "baz"}
+{"name": foz"}' > $RSYSLOG_DYNNAME.inESData.inputfile
+generate_conf
+add_conf '
+global(workDirectory="'$RSYSLOG_DYNNAME.spool'")
+# Note: we must mess up with the template, because we can not
+# instruct ES to put further constraints on the data type and
+# values. So we require integer and make sure it is none.
+template(name="tpl" type="list") {
+ constant(value="{\"")
+ property(name="$!key") constant(value="\":") property(name="$!obj")
+ constant(value="}")
+}
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+module(load="../plugins/imfile/.libs/imfile")
+ruleset(name="foo") {
+ set $!key = "my_obj";
+ set $!obj = $msg;
+ action(type="omelasticsearch"
+ template="tpl"
+ searchIndex="rsyslog_testbench"
+ searchType="test-type"
+ bulkmode="on"
+ serverport="19200"
+ errorFile="./'${RSYSLOG_DYNNAME}'.errorfile"
+ erroronly="on"
+ interleaved="on")
+}
+
+input(type="imfile" File="'$RSYSLOG_DYNNAME.'inESData.inputfile"
+ Tag="foo"
+ Severity="info"
+ ruleset="foo")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+$PYTHON $srcdir/elasticsearch-error-format-check.py errorinterleaved
+
+if [ $? -ne 0 ]
+then
+ echo "error: Format for error file different! " $?
+ exit 1
+fi
+exit_test
diff --git a/tests/es-bulk-errfile-popul-erronly.sh b/tests/es-bulk-errfile-popul-erronly.sh
new file mode 100755
index 0000000..9db619f
--- /dev/null
+++ b/tests/es-bulk-errfile-popul-erronly.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+ensure_elasticsearch_ready
+
+init_elasticsearch
+echo '{ "name" : "foo" }
+{"name": bar"}
+{"name": "baz"}
+{"name": foz"}' > $RSYSLOG_DYNNAME.inESData.inputfile
+generate_conf
+add_conf '
+global(workDirectory="'$RSYSLOG_DYNNAME.spool'")
+# Note: we must mess up with the template, because we can not
+# instruct ES to put further constraints on the data type and
+# values. So we require integer and make sure it is none.
+template(name="tpl" type="list") {
+ constant(value="{\"")
+ property(name="$!key") constant(value="\":") property(name="$!obj")
+ constant(value="}")
+}
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+module(load="../plugins/imfile/.libs/imfile")
+ruleset(name="foo") {
+ set $!key = "my_obj";
+ set $!obj = $msg;
+ action(type="omelasticsearch"
+ template="tpl"
+ searchIndex="rsyslog_testbench"
+ searchType="test-type"
+ serverport="19200"
+ bulkmode="on"
+ errorFile="'${RSYSLOG_DYNNAME}'.errorfile"
+ erroronly="on")
+}
+
+input(type="imfile" File="'$RSYSLOG_DYNNAME.'inESData.inputfile"
+ Tag="foo"
+ Severity="info"
+ ruleset="foo")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+$PYTHON $srcdir/elasticsearch-error-format-check.py erroronly
+
+if [ $? -ne 0 ]
+then
+ echo "error: Format for error file different! " $?
+ error_exit 1
+fi
+exit_test
diff --git a/tests/es-bulk-errfile-popul.sh b/tests/es-bulk-errfile-popul.sh
new file mode 100755
index 0000000..24f1113
--- /dev/null
+++ b/tests/es-bulk-errfile-popul.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+ensure_elasticsearch_ready
+
+init_elasticsearch
+curl -H 'Content-Type: application/json' -XPUT localhost:19200/rsyslog_testbench/ -d '{
+ "mappings": {
+ "test-type": {
+ "properties": {
+ "msgnum": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+}'
+generate_conf
+add_conf '
+# Note: we must mess up with the template, because we can not
+# instruct ES to put further constraints on the data type and
+# values. So we require integer and make sure it is none.
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"x%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+:msg, contains, "msgnum:" action(type="omelasticsearch"
+ template="tpl"
+ searchIndex="rsyslog_testbench"
+ searchType="test-type"
+ serverport="19200"
+ bulkmode="on"
+ errorFile="./'${RSYSLOG_DYNNAME}'.errorfile")
+'
+startup
+injectmsg 0 1000
+shutdown_when_empty
+wait_shutdown
+if [ ! -f ${RSYSLOG_DYNNAME}.errorfile ]
+then
+ echo "error: error file does not exist!"
+ exit 1
+fi
+exit_test
diff --git a/tests/es-bulk-retry.sh b/tests/es-bulk-retry.sh
new file mode 100755
index 0000000..b4bff85
--- /dev/null
+++ b/tests/es-bulk-retry.sh
@@ -0,0 +1,298 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+#export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog"
+
+export ES_PORT=19200
+export NUMMESSAGES=100
+
+# export RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT=120000
+override_test_timeout 120
+#export USE_VALGRIND="YES" # to enable this to run under valgrind
+ensure_elasticsearch_ready --no-start
+
+# change settings to cause bulk rejection errors
+case "$ES_DOWNLOAD" in
+ elasticsearch-5.*) es_option="thread_pool.bulk"
+ es_mapping_uses_type=true
+ es_search_type="test-type" ;;
+ *) es_option="thread_pool.write"
+ es_mapping_uses_type=false
+ es_search_type="_doc" ;;
+esac
+cat >> $dep_work_dir/es/config/elasticsearch.yml <<EOF
+${es_option}.queue_size: 1
+${es_option}.size: 1
+EOF
+start_elasticsearch
+
+generate_conf
+add_conf '
+module(load="../plugins/impstats/.libs/impstats" interval="1"
+ log.file="'$RSYSLOG_DYNNAME'.spool/es-stats.log" log.syslog="off" format="cee")
+
+set $.msgnum = field($msg, 58, 2);
+set $.testval = cnum($.msgnum % 4);
+
+if $.testval == 0 then {
+ # these should be successful
+ set $!msgnum = $.msgnum;
+ set $.extrafield = "notmessage";
+} else if $.testval == 1 then {
+ # these should cause "hard" errors
+ set $!msgnum = "x" & $.msgnum;
+ set $.extrafield = "notmessage";
+} else if $.testval == 2 then {
+ # these should be successful
+ set $!msgnum = $.msgnum;
+ set $.extrafield = "message";
+} else {
+ # these should cause "hard" errors
+ set $!msgnum = "x" & $.msgnum;
+ set $.extrafield = "message";
+}
+
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%$!msgnum%\",\"%$.extrafield%\":\"extrafieldvalue\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+
+template(name="id-template" type="string" string="%$.es_msg_id%")
+
+ruleset(name="error_es") {
+ action(type="omfile" template="RSYSLOG_DebugFormat" file="'$RSYSLOG_DYNNAME'.spool/es-bulk-errors.log")
+}
+
+ruleset(name="try_es") {
+ set $.sendrec = 1;
+ if strlen($.omes!status) > 0 then {
+ # retry case
+ if ($.omes!status == 200) or ($.omes!status == 201) or (($.omes!status == 409) and ($.omes!writeoperation == "create")) then {
+ reset $.sendrec = 0; # successful
+ }
+ if ($.omes!writeoperation == "unknown") or (strlen($.omes!error!type) == 0) or (strlen($.omes!error!reason) == 0) then {
+ call error_es
+ reset $.sendrec = 0;
+ }
+ if ($.omes!status == 400) or ($.omes!status < 200) then {
+ call error_es
+ reset $.sendrec = 0;
+ }
+ if strlen($!notmessage) > 0 then {
+ set $.extrafield = "notmessage";
+ } else {
+ set $.extrafield = "message";
+ }
+ }
+ if $.sendrec == 1 then {
+ if strlen($.omes!_id) > 0 then {
+ set $.es_msg_id = $.omes!_id;
+ } else {
+ # NOTE: in production code, use $uuid - depends on rsyslog being compiled with --enable-uuid
+ set $.es_msg_id = $.msgnum;
+ }
+ action(type="omelasticsearch"
+ server="127.0.0.1"
+ serverport="'${ES_PORT:-19200}'"
+ template="tpl"
+ writeoperation="create"
+ bulkid="id-template"
+ dynbulkid="on"
+ bulkmode="on"
+ retryfailures="on"
+ retryruleset="try_es"
+ searchType="'${es_search_type}'"
+ searchIndex="rsyslog_testbench")
+ }
+}
+
+if $msg contains "msgnum:" then {
+ call try_es
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+if [ "$es_mapping_uses_type" = true ]; then
+ curl -s -H 'Content-Type: application/json' -XPUT localhost:${ES_PORT:-19200}/rsyslog_testbench/ -d '{
+ "mappings": {
+ "test-type": {
+ "properties": {
+ "msgnum": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+}
+' | $PYTHON -mjson.tool
+else
+ # we add 10 shards so we're more likely to get queue rejections
+ curl -s -H 'Content-Type: application/json' -XPUT localhost:${ES_PORT:-19200}/rsyslog_testbench/ -d '{
+ "settings": {
+ "index.number_of_shards": 10
+ },
+ "mappings": {
+ "properties": {
+ "msgnum": {
+ "type": "integer"
+ }
+ }
+ }
+}
+' | $PYTHON -mjson.tool
+fi
+
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="debug.log"
+startup
+if [ -n "${USE_GDB:-}" ] ; then
+ echo attach gdb here
+ sleep 54321 || :
+fi
+success=50
+badarg=50
+./msleep 5000
+injectmsg 0 $NUMMESSAGES
+./msleep 1500; cat $RSYSLOG_OUT_LOG # debuging - we sometimes miss 1 message
+wait_content '"response.success": 50' $RSYSLOG_DYNNAME.spool/es-stats.log
+wait_content '"response.badargument": 50' $RSYSLOG_DYNNAME.spool/es-stats.log
+shutdown_when_empty
+wait_shutdown
+es_getdata $NUMMESSAGES $ES_PORT
+rc=$?
+
+stop_elasticsearch
+cleanup_elasticsearch
+
+if [ -f $RSYSLOG_DYNNAME.work ] ; then
+ < $RSYSLOG_DYNNAME.work \
+ $PYTHON -c '
+import sys,json
+try:
+ # Python 2 forward compatibility
+ range = xrange
+except NameError:
+ pass
+records = int(sys.argv[1])
+extra_recs = open(sys.argv[2], "w")
+missing_recs = open(sys.argv[3], "w")
+expectedrecs = {}
+rc = 0
+nextra = 0
+nmissing = 0
+for ii in range(0, records*2, 2):
+ ss = "{:08}".format(ii)
+ expectedrecs[ss] = ss
+for item in json.load(sys.stdin)["hits"]["hits"]:
+ msgnum = item["_source"]["msgnum"]
+ if msgnum in expectedrecs:
+ del expectedrecs[msgnum]
+ else:
+ extra_recs.write("FAIL: found unexpected msgnum {} in record\n".format(msgnum))
+ nextra += 1
+for item in expectedrecs:
+ missing_recs.write("FAIL: msgnum {} was missing in Elasticsearch\n".format(item))
+ nmissing += 1
+if nextra > 0:
+ print("FAIL: Found {} unexpected records - see {} for the full list.".format(nextra, sys.argv[2]))
+ rc = 1
+if nmissing > 0:
+ print("FAIL: Found {} missing records - see {} for the full list.".format(nmissing, sys.argv[3]))
+ rc = 1
+sys.exit(rc)
+' $success ${RSYSLOG_DYNNAME}.spool/extra_records ${RSYSLOG_DYNNAME}.spool/missing_records || { rc=$?; errmsg="FAIL: found unexpected or missing records in Elasticsearch"; }
+ if [ $rc = 0 ] ; then
+ echo "good - no missing or unexpected records were found in Elasticsearch"
+ fi
+else
+ errmsg="FAIL: elasticsearch output file $RSYSLOG_DYNNAME.work not found"
+ rc=1
+fi
+
+if [ -f ${RSYSLOG_DYNNAME}.spool/es-stats.log ] ; then
+ $PYTHON < ${RSYSLOG_DYNNAME}.spool/es-stats.log -c '
+import sys,json
+success = int(sys.argv[1])
+badarg = int(sys.argv[2])
+lasthsh = {}
+rc = 0
+for line in sys.stdin:
+ jstart = line.find("{")
+ if jstart >= 0:
+ hsh = json.loads(line[jstart:])
+ if hsh["name"] == "omelasticsearch":
+ lasthsh = hsh
+actualsuccess = lasthsh["response.success"]
+actualbadarg = lasthsh["response.badargument"]
+actualrej = lasthsh["response.bulkrejection"]
+actualsubmitted = lasthsh["submitted"]
+if actualsuccess != success:
+ print("FAIL: expected {} successful responses but omelasticsearch stats reported {}".format(success, actualsuccess))
+ rc = 1
+if actualbadarg != badarg:
+ print("FAIL: expected {} bad argument errors but omelasticsearch stats reported {}".format(badarg, actualbadarg))
+ rc = 1
+if actualrej == 0:
+ print("FAIL: there were no bulk index rejections reported by Elasticsearch")
+ rc = 1
+if actualsuccess + actualbadarg + actualrej != actualsubmitted:
+ print("FAIL: The sum of the number of successful responses and bad argument errors and bulk index rejections {} did not equal the number of requests actually submitted to Elasticsearch {}".format(actualsuccess + actualbadarg + actualrej, actualsubmitted))
+ rc = 1
+sys.exit(rc)
+' $success $badarg || { rc=$?; errmsg="FAIL: expected responses not found in ${RSYSLOG_DYNNAME}.spool/es-stats.log"; }
+ if [ $rc = 0 ] ; then
+ echo "good - all expected stats were found in Elasticsearch stats file ${RSYSLOG_DYNNAME}.spool/es-stats.log"
+ fi
+else
+ errmsg="FAIL: stats file ${RSYSLOG_DYNNAME}.spool/es-stats.log not found"
+ rc=1
+fi
+
+if [ -f ${RSYSLOG_DYNNAME}.spool/es-bulk-errors.log ] ; then
+ found=0
+ for ii in $(seq --format="x%08.f" 1 2 $(expr 2 \* $badarg)) ; do
+ if grep -q '^[$][!]:{.*"msgnum": "'$ii'"' ${RSYSLOG_DYNNAME}.spool/es-bulk-errors.log ; then
+ (( found++ ))
+ else
+ errmsg="FAIL: missing message $ii in ${RSYSLOG_DYNNAME}.spool/es-bulk-errors.log"
+ rc=1
+ fi
+ done
+ if [ $found -ne $badarg ] ; then
+ errmsg="FAIL: found only $found of $badarg messages in ${RSYSLOG_DYNNAME}.spool/es-bulk-errors.log"
+ rc=1
+ fi
+ if grep -q '^[$][.]:{.*"omes": {' ${RSYSLOG_DYNNAME}.spool/es-bulk-errors.log ; then
+ :
+ else
+ errmsg="FAIL: es response info not found in ${RSYSLOG_DYNNAME}.spool/es-bulk-errors.log"
+ rc=1
+ fi
+ if grep -q '^[$][.]:{.*"status": 400' ${RSYSLOG_DYNNAME}.spool/es-bulk-errors.log ; then
+ :
+ else
+ errmsg="FAIL: status 400 not found in ${RSYSLOG_DYNNAME}.spool/es-bulk-errors.log"
+ rc=1
+ fi
+else
+ errmsg="FAIL: bulk error file ${RSYSLOG_DYNNAME}.spool/es-bulk-errors.log not found"
+ rc=1
+fi
+
+if [ $rc -eq 0 ] ; then
+ echo tests completed successfully
+else
+ cat $RSYSLOG_OUT_LOG
+ if [ -f ${RSYSLOG_DYNNAME}.spool/es-stats.log ] ; then
+ cat ${RSYSLOG_DYNNAME}.spool/es-stats.log
+ fi
+ if [ -f ${RSYSLOG_DYNNAME}.spool/es-bulk-errors.log ] ; then
+ cat ${RSYSLOG_DYNNAME}.spool/es-bulk-errors.log
+ fi
+ printf '\n%s\n' "$errmsg"
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/es-duplicated-ruleset-vg.sh b/tests/es-duplicated-ruleset-vg.sh
new file mode 100755
index 0000000..06e58d5
--- /dev/null
+++ b/tests/es-duplicated-ruleset-vg.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+echo temporarily disabled because it fails quite often - fix in progress
+exit 77
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/es-duplicated-ruleset.sh
diff --git a/tests/es-duplicated-ruleset.sh b/tests/es-duplicated-ruleset.sh
new file mode 100755
index 0000000..b61b091
--- /dev/null
+++ b/tests/es-duplicated-ruleset.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# The sole purpose of this test is to check that rsyslog "survives" the
+# duplicate ruleset definition and emits the proper error message. So we
+# do NOT need to have elasticsearch running to carry it out. We avoid
+# sending data to ES as this complicates things more than needed.
+# This is based on a real case, see
+# https://github.com/rsyslog/rsyslog/pull/3796
+# Thanks to Noriko Hosoi for providing the original test idea which
+# was then modified by Rainer Gerhards.
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_PORT=19200
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+generate_conf
+add_conf '
+template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+ruleset(name="try_es") {
+ action(type="omelasticsearch"
+ server="localhost"
+ serverport=`echo $ES_PORT`
+ template="tpl"
+ searchIndex="rsyslog_testbench"
+ retryruleset="try_es"
+ )
+}
+
+ruleset(name="try_es") {
+ action(type="omelasticsearch"
+ server="localhost"
+ serverport=`echo $ES_PORT`
+ template="tpl"
+ searchIndex="rsyslog_testbench"
+ retryruleset="try_es"
+ )
+}
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_immediate
+wait_shutdown
+content_check "ruleset 'try_es' specified more than once"
+exit_test
diff --git a/tests/es-execOnlyWhenPreviousSuspended.sh b/tests/es-execOnlyWhenPreviousSuspended.sh
new file mode 100755
index 0000000..4b72377
--- /dev/null
+++ b/tests/es-execOnlyWhenPreviousSuspended.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100 #10000
+ensure_elasticsearch_ready
+
+init_elasticsearch
+
+generate_conf
+add_conf '
+template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}")
+template(name="tpl2" type="string" string="%msg:F,58:2%\n")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+
+if $msg contains "msgnum:" then {
+ action(type="omelasticsearch"
+ server="127.0.0.1"
+ serverport="19200"
+ template="tpl"
+ searchIndex="rsyslog_testbench"
+ action.resumeInterval="2"
+ action.resumeretrycount="1")
+
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="tpl2"
+ action.execOnlyWhenPreviousIsSuspended="on")
+
+ # this action just to count processed messages
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.syncfile")
+}
+'
+startup
+injectmsg 0 $NUMMESSAGES
+wait_file_lines $RSYSLOG_DYNNAME.syncfile $NUMMESSAGES
+stop_elasticsearch
+./msleep 1000
+injectmsg $NUMMESSAGES 1
+wait_file_lines $RSYSLOG_DYNNAME.syncfile $((NUMMESSAGES + 1))
+wait_queueempty
+injectmsg $(( NUMMESSAGES + 1 )) $NUMMESSAGES
+wait_file_lines $RSYSLOG_DYNNAME.syncfile $((NUMMESSAGES + 1 + NUMMESSAGES))
+start_elasticsearch
+
+shutdown_when_empty
+wait_shutdown
+
+seq_check $(( NUMMESSAGES + 1 )) $(( NUMMESSAGES * 2 ))
+es_getdata $NUMMESSAGES 19200
+seq_check 0 $(( NUMMESSAGES - 1 ))
+exit_test
diff --git a/tests/es-maxbytes-bulk.sh b/tests/es-maxbytes-bulk.sh
new file mode 100755
index 0000000..99a4afa
--- /dev/null
+++ b/tests/es-maxbytes-bulk.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_DOWNLOAD=elasticsearch-6.0.0.tar.gz
+export ES_PORT=19200
+export NUMMESSAGES=10000
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+ensure_elasticsearch_ready
+
+init_elasticsearch
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+:msg, contains, "msgnum:" action(type="omelasticsearch"
+ template="tpl"
+ serverport="'$ES_PORT'"
+ searchIndex="rsyslog_testbench"
+ bulkmode="on"
+ maxbytes="1k")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+es_getdata $NUMMESSAGES $ES_PORT
+seq_check
+exit_test
diff --git a/tests/es-searchType-empty.sh b/tests/es-searchType-empty.sh
new file mode 100755
index 0000000..bc0b01e
--- /dev/null
+++ b/tests/es-searchType-empty.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export ES_PORT=19200
+# Using the default will cause deprecation failures
+export ES_PORT_OPTION="transport.port"
+export NUMMESSAGES=2000 # slow test
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+ensure_elasticsearch_ready
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+
+if $msg contains "msgnum:" then
+ action(type="omelasticsearch"
+ server="127.0.0.1"
+ serverport="19200"
+ searchType=""
+ template="tpl"
+ searchIndex="rsyslog_testbench")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+es_getdata
+seq_check
+if grep "DEPRECATION" $dep_work_dir/es/logs/rsyslog-testbench_deprecation.log; then
+ echo "Found deprecations, failing!"
+ exit 1
+fi
+exit_test
diff --git a/tests/es-writeoperation.sh b/tests/es-writeoperation.sh
new file mode 100755
index 0000000..846f2f7
--- /dev/null
+++ b/tests/es-writeoperation.sh
@@ -0,0 +1,118 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+ensure_elasticsearch_ready
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+
+if $msg contains "msgnum:" then
+ action(type="omelasticsearch"
+ server="127.0.0.1"
+ serverport="19200"
+ template="tpl"
+ writeoperation="create"
+ searchIndex="rsyslog_testbench")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+if grep -q "omelasticsearch: writeoperation '1' requires bulkid" $RSYSLOG_OUT_LOG ; then
+ echo found correct error message
+else
+ echo Error: did not complain about incorrect writeoperation
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+
+if $msg contains "msgnum:" then
+ action(type="omelasticsearch"
+ server="127.0.0.1"
+ serverport="19200"
+ template="tpl"
+ writeoperation="unknown"
+ searchIndex="rsyslog_testbench")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+if grep -q "omelasticsearch: invalid value 'unknown' for writeoperation" $RSYSLOG_OUT_LOG ; then
+ echo found correct error message
+else
+ echo Error: did not complain about incorrect writeoperation
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/omelasticsearch/.libs/omelasticsearch")
+
+template(name="id-template" type="list") { constant(value="123456789") }
+
+if $msg contains "msgnum:" then
+ action(type="omelasticsearch"
+ server="127.0.0.1"
+ serverport="19200"
+ template="tpl"
+ writeoperation="create"
+ bulkid="id-template"
+ dynbulkid="on"
+ bulkmode="on"
+ searchIndex="rsyslog_testbench")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+init_elasticsearch
+
+export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check
+export NUMMESSAGES=1
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+es_getdata 1 $ES_PORT
+
+$PYTHON <$RSYSLOG_DYNNAME.work -c '
+import sys,json
+hsh = json.load(sys.stdin)
+try:
+ if hsh["hits"]["hits"][0]["_id"] == "123456789":
+ print("good - found expected value")
+ sys.exit(0)
+ print("Error: _id not expected value 123456789:", hsh["hits"]["hits"][0]["_id"])
+ sys.exit(1)
+except ValueError:
+ print("Error: output is not valid:", json.dumps(hsh,indent=2))
+ sys.exit(1)
+'
+
+if [ $? -eq 0 ] ; then
+ echo found correct response
+else
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+exit_test
diff --git a/tests/es_response_get_msgnum.py b/tests/es_response_get_msgnum.py
new file mode 100644
index 0000000..f8a5ed4
--- /dev/null
+++ b/tests/es_response_get_msgnum.py
@@ -0,0 +1,8 @@
+import json
+import os
+
+with open(os.environ['RSYSLOG_DYNNAME'] + ".work") as json_file:
+ json_data = json.load(json_file)
+ json_data = json_data["hits"]
+ for item in json_data["hits"]:
+ print(item["_source"]["msgnum"])
diff --git a/tests/exec_tpl-concurrency.sh b/tests/exec_tpl-concurrency.sh
new file mode 100755
index 0000000..af4bb0d
--- /dev/null
+++ b/tests/exec_tpl-concurrency.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Test concurrency of exec_template function with msg variables
+# Added 2015-12-11 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on all flavors of Solaris."
+export NUMMESSAGES=500000
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="interim" type="string" string="%$!tree!here!nbr%")
+template(name="outfmt" type="string" string="%$!interim%\n")
+template(name="all-json" type="string" string="%$!%\n")
+
+if $msg contains "msgnum:" then {
+ set $!tree!here!nbr = field($msg, 58, 2);
+ action(type="omfile" file="'$RSYSLOG2_OUT_LOG'" template="all-json"
+ queue.type="linkedList")
+
+ set $!interim = exec_template("interim");
+ unset $!tree!here!nbr;
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt"
+ queue.type="fixedArray")
+}
+'
+startup
+tcpflood -m$NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/execonlyonce.sh b/tests/execonlyonce.sh
new file mode 100755
index 0000000..5ab9739
--- /dev/null
+++ b/tests/execonlyonce.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Test for the $ActionExecOnlyOnceEveryInterval directive.
+# We inject a couple of messages quickly during the interval,
+# then wait until the interval expires, then quickly inject
+# another set. After that, it is checked if exactly two messages
+# have arrived.
+# The once interval must be set to 3 seconds in the config file.
+# added 2009-11-12 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'")
+$ActionExecOnlyOnceEveryInterval 3
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+tcpflood -m10 -i1
+# now wait until the interval definitely expires (at least we hope so...)
+printf 'wainting for interval to expire...\n'
+sleep 5
+# and inject another couple of messages
+tcpflood -m10 -i100
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="00000001
+00000100"
+cmp_exact
+exit_test
diff --git a/tests/execonlywhenprevsuspended-nonsusp-queue.sh b/tests/execonlywhenprevsuspended-nonsusp-queue.sh
new file mode 100755
index 0000000..eb5b87b
--- /dev/null
+++ b/tests/execonlywhenprevsuspended-nonsusp-queue.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# check if execonly...suspended works when the first action is *not*
+# suspended --> file1 must be created, file 2 not
+# rgerhards, 2015-05-27
+echo =====================================================================================
+echo \[execonlywhenprevsuspended-nonsusp-queue\]: test execonly...suspended functionality with non-suspended action and queue
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+main_queue(queue.workerthreads="1")
+
+# omtesting provides the ability to cause "SUSPENDED" action state
+module(load="../plugins/omtesting/.libs/omtesting")
+
+$MainMsgQueueTimeoutShutdown 100000
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+:msg, contains, "msgnum:" {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt" name="ok")
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`
+ template="outfmt" name="susp"
+ queue.type="linkedList"
+ action.ExecOnlyWhenPreviousIsSuspended="on"
+ )
+}
+'
+startup
+injectmsg 0 1000
+shutdown_when_empty
+wait_shutdown
+ls *.out.log
+seq_check 0 999
+if [ -e ${RSYSLOG2_OUT_LOG} ]; then
+ echo "error: \"suspended\" file exists, first 10 lines:"
+ $RS_HEADCMD ${RSYSLOG2_OUT_LOG}
+ exit 1
+fi
+exit_test
diff --git a/tests/execonlywhenprevsuspended-nonsusp.sh b/tests/execonlywhenprevsuspended-nonsusp.sh
new file mode 100755
index 0000000..c2d9ae2
--- /dev/null
+++ b/tests/execonlywhenprevsuspended-nonsusp.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# check if execonly...suspended works when the first action is *not*
+# suspended --> file1 must be created, file 2 not
+# rgerhards, 2015-05-27
+echo =====================================================================================
+echo \[execonlywhenprevsuspended-nonsusp\]: test execonly...suspended functionality with non-suspended action
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+main_queue(queue.workerthreads="1")
+
+# omtesting provides the ability to cause "SUSPENDED" action state
+module(load="../plugins/omtesting/.libs/omtesting")
+
+$MainMsgQueueTimeoutShutdown 100000
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+:msg, contains, "msgnum:" {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt"
+ action.ExecOnlyWhenPreviousIsSuspended="on"
+ )
+}
+'
+startup
+injectmsg 0 1000
+shutdown_when_empty
+wait_shutdown
+seq_check 0 999
+if [ -e ${RSYSLOG2_OUT_LOG} ]; then
+ echo "error: \"suspended\" file exists, first 10 lines:"
+ $RS_HEADCMD ${RSYSLOG2_OUT_LOG}
+ exit 1
+fi
+exit_test
diff --git a/tests/execonlywhenprevsuspended-queue.sh b/tests/execonlywhenprevsuspended-queue.sh
new file mode 100755
index 0000000..6bd82b0
--- /dev/null
+++ b/tests/execonlywhenprevsuspended-queue.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# rgerhards, 2015-05-27
+echo =====================================================================================
+echo \[execonlywhenprevsuspended-queue.sh\]: test execonly...suspended functionality with action on its own queue
+
+uname
+if [ $(uname) = "SunOS" ] ; then
+ echo "This test currently does not work on all flavors of Solaris."
+ exit 77
+fi
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+main_queue(queue.workerthreads="1")
+
+# omtesting provides the ability to cause "SUSPENDED" action state
+module(load="../plugins/omtesting/.libs/omtesting")
+
+$MainMsgQueueTimeoutShutdown 100000
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+:msg, contains, "msgnum:" {
+ :omtesting:fail 2 0 # omtesting has only legacy params!
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt"
+ queue.type="linkedList"
+ action.ExecOnlyWhenPreviousIsSuspended="on"
+ )
+}
+'
+startup
+injectmsg 0 1000
+shutdown_when_empty
+wait_shutdown
+seq_check 1 999
+exit_test
diff --git a/tests/execonlywhenprevsuspended.sh b/tests/execonlywhenprevsuspended.sh
new file mode 100755
index 0000000..9560241
--- /dev/null
+++ b/tests/execonlywhenprevsuspended.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# we test the execonly if previous is suspended directive. This is the
+# most basic test which solely tests a single case but no dependencies within
+# the ruleset.
+# rgerhards, 2010-06-23
+echo =====================================================================================
+echo \[execonlywhenprevsuspended.sh\]: test execonly...suspended functionality simple case
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+main_queue(queue.workerthreads="1")
+
+# omtesting provides the ability to cause "SUSPENDED" action state
+$ModLoad ../plugins/omtesting/.libs/omtesting
+
+$MainMsgQueueTimeoutShutdown 100000
+$template outfmt,"%msg:F,58:2%\n"
+
+:msg, contains, "msgnum:" :omtesting:fail 2 0
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"';outfmt
+'
+startup
+injectmsg 0 1000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 1 999
+exit_test
diff --git a/tests/execonlywhenprevsuspended2.sh b/tests/execonlywhenprevsuspended2.sh
new file mode 100755
index 0000000..4b54d17
--- /dev/null
+++ b/tests/execonlywhenprevsuspended2.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# we test the execonly if previous is suspended directive. For this,
+# we have an action that is suspended for all messages but the second.
+# we write two files: one only if the output is suspended and the other one
+# in all cases. This should thoroughly check the logic involved.
+# rgerhards, 2010-06-23
+echo ===============================================================================
+echo \[execonlywhenprevsuspended2.sh\]: test execonly...suspended functionality
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# omtesting provides the ability to cause "SUSPENDED" action state
+$ModLoad ../plugins/omtesting/.libs/omtesting
+
+$MainMsgQueueTimeoutShutdown 100000
+$template outfmt,"%msg:F,58:2%\n"
+
+:msg, contains, "msgnum:" :omtesting:fail 2 0
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"';outfmt
+# note that we MUST re-set PrevSusp, else it will remain active
+# for all other actions as well (this tells us how bad the current
+# config language is...). -- rgerhards, 2010-06-24
+$ActionExecOnlyWhenPreviousIsSuspended off
+
+:msg, contains, "msgnum:" ./'"${RSYSLOG2_OUT_LOG}"';outfmt
+'
+startup
+injectmsg 0 1000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+echo check file 1
+seq_check 1 999
+echo check file 2
+seq_check2 0 999
+exit_test
diff --git a/tests/execonlywhenprevsuspended3.sh b/tests/execonlywhenprevsuspended3.sh
new file mode 100755
index 0000000..b4c60be
--- /dev/null
+++ b/tests/execonlywhenprevsuspended3.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# we test the execonly if previous is suspended directive.
+# This test checks if, within the same rule, one action can be set
+# to emit only if the previous was suspended while the next action
+# always sends data.
+# rgerhards, 2010-06-24
+echo ===============================================================================
+echo \[execonlywhenprevsuspended3.sh\]: test execonly...suspended functionality
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# omtesting provides the ability to cause "SUSPENDED" action state
+$ModLoad ../plugins/omtesting/.libs/omtesting
+
+$MainMsgQueueTimeoutShutdown 100000
+$template outfmt,"%msg:F,58:2%\n"
+
+:msg, contains, "msgnum:" :omtesting:fail 2 0
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"';outfmt
+# note that we MUST re-set PrevSusp, else it will remain active
+# for all other actions as well (this tells us how bad the current
+# config language is...). -- rgerhards, 2010-06-24
+$ActionExecOnlyWhenPreviousIsSuspended off
+& ./'"${RSYSLOG2_OUT_LOG}"';outfmt
+'
+startup
+injectmsg 0 1000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+echo check file 1
+seq_check 1 999
+echo check file 2
+seq_check2 0 999
+exit_test
diff --git a/tests/execonlywhenprevsuspended4.sh b/tests/execonlywhenprevsuspended4.sh
new file mode 100755
index 0000000..c9cd599
--- /dev/null
+++ b/tests/execonlywhenprevsuspended4.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# we test the execonly if previous is suspended directive.
+# This test checks if multiple backup actions can be defined.
+# rgerhards, 2010-06-24
+echo ===============================================================================
+echo \[execonlywhenprevsuspended4.sh\]: test execonly..suspended multi backup action
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# omtesting provides the ability to cause "SUSPENDED" action state
+$ModLoad ../plugins/omtesting/.libs/omtesting
+
+$MainMsgQueueTimeoutShutdown 100000
+$template outfmt,"%msg:F,58:2%\n"
+
+:msg, contains, "msgnum:" :omtesting:fail 2 0
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"';outfmt
+# note that $ActionExecOnlyWhenPreviousIsSuspended on is still active!
+& ./'"${RSYSLOG2_OUT_LOG}"';outfmt
+'
+startup
+injectmsg 0 1000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 1 999
+if [[ -s ${RSYSLOG2_OUT_LOG} ]] ; then
+ echo failure: second output file has data where it should be empty
+ exit 1
+fi ;
+exit_test
diff --git a/tests/execonlywhenprevsuspended_multiwrkr.sh b/tests/execonlywhenprevsuspended_multiwrkr.sh
new file mode 100755
index 0000000..9629ff9
--- /dev/null
+++ b/tests/execonlywhenprevsuspended_multiwrkr.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# rgerhards, 2013-12-05
+echo =====================================================================================
+echo \[execonlywhenprevsuspended_multiwrkr.sh\]: test execonly...suspended functionality multiworker case
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# omtesting provides the ability to cause "SUSPENDED" action state
+$ModLoad ../plugins/omtesting/.libs/omtesting
+
+$MainMsgQueueTimeoutShutdown 100000
+$template outfmt,"%msg:F,58:2%\n"
+
+:msg, contains, "msgnum:" :omtesting:fail 2 0
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"';outfmt
+'
+startup
+# we initially send only 10 messages. It has shown that if we send more,
+# we cannot really control which are the first two messages imdiag sees,
+# and so we do not know for sure which numbers are skipped. So we inject
+# those 10 to get past that point.
+injectmsg 0 10
+./msleep 500
+injectmsg 10 990
+shutdown_when_empty
+wait_shutdown
+seq_check 1 999
+exit_test
diff --git a/tests/externalstate-failed-rcvr.sh b/tests/externalstate-failed-rcvr.sh
new file mode 100755
index 0000000..b3f23ca
--- /dev/null
+++ b/tests/externalstate-failed-rcvr.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# This tests the action suspension via a file and ensure that it does
+# NOT override actual target suspension state.
+# This file is part of the rsyslog project, released under ASL 2.0
+# Written 2019-01-08 by Rainer Gerhards
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=2500
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+
+# IMPORTANT: nothing permitted to listen on $TCPFLOOD_PORT!
+# mimic some good state in external statefile:
+printf "%s" "READY" > $RSYSLOG_DYNNAME.STATE
+
+generate_conf
+add_conf '
+$template outfmt,"%msg:F,58:2%\n"
+
+:msg, contains, "msgnum:" {
+ action(name="primary" type="omfwd" target="localhost" port="'$TCPFLOOD_PORT'"
+ protocol="tcp" action.externalstate.file="'$RSYSLOG_DYNNAME'.STATE")
+ action(name="failover" type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt"
+ action.execOnlyWhenPreviousIsSuspended="on")
+}
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+# note: we do NOT need to do a check_seq as this was already done as part of the
+# queue empty predicate check
+exit_test
diff --git a/tests/fac_authpriv.sh b/tests/fac_authpriv.sh
new file mode 100755
index 0000000..08e3c0d
--- /dev/null
+++ b/tests/fac_authpriv.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# This tests proper processing of the authpriv facility.
+# added 2014-09-16 by Rgerhards
+
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n"
+authpriv.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -P 81
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/fac_ftp.sh b/tests/fac_ftp.sh
new file mode 100755
index 0000000..05b00db
--- /dev/null
+++ b/tests/fac_ftp.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n"
+ftp.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -P 89
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/fac_invld1.sh b/tests/fac_invld1.sh
new file mode 100755
index 0000000..34b9e5f
--- /dev/null
+++ b/tests/fac_invld1.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2014-10-01 by Rgerhards
+
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(type="string" name="outfmt" string="%msg:F,58:4%\n")
+invld.=debug action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -P 1011
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/fac_invld2.sh b/tests/fac_invld2.sh
new file mode 100755
index 0000000..21b1bde
--- /dev/null
+++ b/tests/fac_invld2.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2014-10-01 by Rgerhards
+
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(type="string" name="outfmt" string="%msg:F,58:4%\n")
+invld.=debug action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -P 3500000000
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/fac_invld3.sh b/tests/fac_invld3.sh
new file mode 100755
index 0000000..e0bcb3d
--- /dev/null
+++ b/tests/fac_invld3.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2014-10-01 by Rgerhards
+
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(type="string" name="outfmt" string="%msg:F,58:4%\n")
+invld.=debug action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -P x112
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/fac_invld4_rfc5424.sh b/tests/fac_invld4_rfc5424.sh
new file mode 100755
index 0000000..991a7b2
--- /dev/null
+++ b/tests/fac_invld4_rfc5424.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2014-10-01 by Rgerhards
+
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(type="string" name="outfmt" string="%msg:F,58:4%\n")
+invld.=debug action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -y -m$NUMMESSAGES -P 8000000000000000000000000000000
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/fac_local0-vg.sh b/tests/fac_local0-vg.sh
new file mode 100755
index 0000000..dd684b5
--- /dev/null
+++ b/tests/fac_local0-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# addd 2020-01-19 by RGerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/fac_local0.sh
diff --git a/tests/fac_local0.sh b/tests/fac_local0.sh
new file mode 100755
index 0000000..c6a2006
--- /dev/null
+++ b/tests/fac_local0.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# added 2014-09-17 by Rgerhards
+
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(type="string" name="outfmt" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+if $syslogfacility-text == "local0" then
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -P 129
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/fac_local7.sh b/tests/fac_local7.sh
new file mode 100755
index 0000000..f078422
--- /dev/null
+++ b/tests/fac_local7.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2014-09-24 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(type="string" name="outfmt" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+if $syslogfacility-text == "local7" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -P 185
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/fac_mail.sh b/tests/fac_mail.sh
new file mode 100755
index 0000000..b222975
--- /dev/null
+++ b/tests/fac_mail.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# added 2014-09-17 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(type="string" name="outfmt" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+mail.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -P 17
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/fac_news.sh b/tests/fac_news.sh
new file mode 100755
index 0000000..01c7b01
--- /dev/null
+++ b/tests/fac_news.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2014-09-17 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(type="string" name="outfmt" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+if prifilt("news.*") then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -P 57
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/fac_ntp.sh b/tests/fac_ntp.sh
new file mode 100755
index 0000000..d609663
--- /dev/null
+++ b/tests/fac_ntp.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n"
+ntp.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -P 97
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/fac_uucp.sh b/tests/fac_uucp.sh
new file mode 100755
index 0000000..c566276
--- /dev/null
+++ b/tests/fac_uucp.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2014-09-17 by Rgerhards
+
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(type="string" name="outfmt" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+uucp.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -P 65
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/failover-async.sh b/tests/failover-async.sh
new file mode 100755
index 0000000..2b8f0ff
--- /dev/null
+++ b/tests/failover-async.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo \[failover-async.sh\]: async test for failover functionality
+
+uname
+if [ $(uname) = "SunOS" ] ; then
+ echo "This test currently does not work on all flavors of Solaris."
+ exit 77
+fi
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$template outfmt,"%msg:F,58:2%\n"
+# note: the target server shall not be available!
+
+$ActionQueueType LinkedList
+:msg, contains, "msgnum:" @@127.0.0.1:13514
+& ./'"${RSYSLOG_OUT_LOG}"';outfmt
+'
+startup
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/failover-basic-vg.sh b/tests/failover-basic-vg.sh
new file mode 100755
index 0000000..ceb3bdb
--- /dev/null
+++ b/tests/failover-basic-vg.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[failover-basic.sh\]: basic test for failover functionality
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$template outfmt,"%msg:F,58:2%\n"
+# note: the target server shall not be available!
+:msg, contains, "msgnum:" @@127.0.0.1:13514
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"';outfmt
+'
+startup_vg
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+seq_check 0 4999
+exit_test
diff --git a/tests/failover-basic.sh b/tests/failover-basic.sh
new file mode 100755
index 0000000..a979bdd
--- /dev/null
+++ b/tests/failover-basic.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo \[failover-basic.sh\]: basic test for failover functionality
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$template outfmt,"%msg:F,58:2%\n"
+# note: the target server shall not be available!
+:msg, contains, "msgnum:" @@127.0.0.1:13514
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"';outfmt
+'
+startup
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/failover-double.sh b/tests/failover-double.sh
new file mode 100755
index 0000000..6aa7205
--- /dev/null
+++ b/tests/failover-double.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export DEAD_PORT=4 # a port unassigned by IANA and very unlikely to be used
+generate_conf
+add_conf '
+$template outfmt,"%msg:F,58:2%\n"
+
+:msg, contains, "msgnum:" @@127.0.0.1:'$DEAD_PORT'
+$ActionExecOnlyWhenPreviousIsSuspended on
+& @@127.0.0.1:1234
+& ./'"${RSYSLOG_OUT_LOG}"';outfmt
+$ActionExecOnlyWhenPreviousIsSuspended off
+'
+startup
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/failover-no-basic-vg.sh b/tests/failover-no-basic-vg.sh
new file mode 100755
index 0000000..0c6dba4
--- /dev/null
+++ b/tests/failover-no-basic-vg.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[failover-no-basic.sh\]: basic test for failover functionality - no failover
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$RepeatedMsgReduction off
+
+# second action should never execute
+:msg, contains, "msgnum:" /dev/null
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"'
+'
+startup_vg
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+# now we need our custom logic to see if the result file is empty
+# (what it should be!)
+cmp $RSYSLOG_OUT_LOG /dev/null
+if [ $? -eq 1 ]
+then
+ echo "ERROR, output file not empty"
+ exit 1
+fi
+exit_test
diff --git a/tests/failover-no-basic.sh b/tests/failover-no-basic.sh
new file mode 100755
index 0000000..9c4a47e
--- /dev/null
+++ b/tests/failover-no-basic.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo \[failover-no-basic.sh\]: basic test for failover functionality - no failover
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$RepeatedMsgReduction off
+
+# second action should never execute
+:msg, contains, "msgnum:" /dev/null
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"'
+'
+startup
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+# now we need our custom logic to see if the result file is empty
+# (what it should be!)
+cmp $RSYSLOG_OUT_LOG /dev/null
+if [ $? -eq 1 ]
+then
+ echo "ERROR, output file not empty"
+ exit 1
+fi
+exit_test
diff --git a/tests/failover-no-rptd-vg.sh b/tests/failover-no-rptd-vg.sh
new file mode 100755
index 0000000..66cc838
--- /dev/null
+++ b/tests/failover-no-rptd-vg.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# rptd test for failover functionality - no failover
+# This file is part of the rsyslog project, released under GPLv3
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$RepeatedMsgReduction on
+
+# second action should never execute
+:msg, contains, "msgnum:" /dev/null
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"'
+'
+startup_vg
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+# now we need our custom logic to see if the result file is empty
+# (what it should be!)
+if [ -f $RSYSLOG_OUT_LOG -a "$(cat $RSYSLOG_OUT_LOG)" != "" ]; then
+ echo "ERROR, output file not empty"
+ cat -n "$RSYSLOG_OUT_LOG"
+ error_exit 1
+fi
+exit_test
diff --git a/tests/failover-no-rptd.sh b/tests/failover-no-rptd.sh
new file mode 100755
index 0000000..4d6d4d9
--- /dev/null
+++ b/tests/failover-no-rptd.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo \[failover-no-rptd.sh\]: rptd test for failover functionality - no failover
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$RepeatedMsgReduction on
+
+# second action should never execute
+:msg, contains, "msgnum:" /dev/null
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"'
+'
+startup
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+# now we need our custom logic to see if the result file is empty
+# (what it should be!)
+cmp $RSYSLOG_OUT_LOG /dev/null
+if [ $? -eq 1 ]
+then
+ echo "ERROR, output file not empty"
+ exit 1
+fi
+exit_test
diff --git a/tests/failover-rptd-vg.sh b/tests/failover-rptd-vg.sh
new file mode 100755
index 0000000..d730013
--- /dev/null
+++ b/tests/failover-rptd-vg.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[failover-rptd.sh\]: rptd test for failover functionality
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$RepeatedMsgReduction on
+
+$template outfmt,"%msg:F,58:2%\n"
+# note: the target server shall not be available!
+:msg, contains, "msgnum:" @@127.0.0.1:13514
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'"${RSYSLOG_OUT_LOG}"';outfmt
+'
+startup_vg
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+seq_check 0 4999
+exit_test
diff --git a/tests/failover-rptd.sh b/tests/failover-rptd.sh
new file mode 100755
index 0000000..0e45afa
--- /dev/null
+++ b/tests/failover-rptd.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# rptd test for failover functionality
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+NUMMESSAGES=5000
+generate_conf
+add_conf '
+$RepeatedMsgReduction on
+
+$template outfmt,"%msg:F,58:2%\n"
+# note: the target server shall not be available!
+:msg, contains, "msgnum:" @@127.0.0.1:'$TCPFLOOD_PORT'
+$ActionExecOnlyWhenPreviousIsSuspended on
+& ./'$RSYSLOG_OUT_LOG';outfmt
+'
+startup
+injectmsg 0 $NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/faketime_common.sh b/tests/faketime_common.sh
new file mode 100644
index 0000000..2fab082
--- /dev/null
+++ b/tests/faketime_common.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+# addd 2016-03-11 by Thomas D., released under ASL 2.0
+# Several tests make use of faketime. They all need to know when
+# faketime is missing or the system isn't year-2038 complaint.
+# This script can be sourced to prevent duplicated code.
+
+rsyslog_testbench_preload_libfaketime() {
+ local missing_requirements=
+ if ! hash find 2>/dev/null ; then
+ missing_requirements="'find' is missing in PATH; Make sure you have findutils/coreutils installed! Skipping test ..."
+ fi
+
+ if ! hash $RS_SORTCMD 2>/dev/null ; then
+ missing_requirements="'sort' is missing in PATH; Make sure you have coreutils installed! Skipping test ..."
+ fi
+
+ if ! hash $RS_HEADCMD 2>/dev/null ; then
+ missing_requirements="'head' is missing in PATH; Make sure you have coreutils installed! Skipping test ..."
+ fi
+
+ if [ -n "${missing_requirements}" ]; then
+ printf '%s\n' "${missing_requirements}"
+ exit 77
+ fi
+
+ RSYSLOG_LIBFAKETIME=$(find /usr -name 'libfaketime.so*' -type f | $RS_SORTCMD --reverse | $RS_HEADCMD --lines 1)
+ if [ -z "${RSYSLOG_LIBFAKETIME}" ]; then
+ echo "Could not determine libfaketime library, skipping test!"
+ exit 77
+ fi
+
+ echo "Testing '${RSYSLOG_LIBFAKETIME}' library ..."
+ local faketime_testtime=$(LD_PRELOAD="${RSYSLOG_LIBFAKETIME}" FAKETIME="1991-08-25 20:57:08" TZ=GMT date +%s 2>/dev/null)
+ if [ ${faketime_testtime} -ne 683153828 ] ; then
+ echo "'${RSYSLOG_LIBFAKETIME}' failed sanity check, skipping test!"
+ exit 77
+ else
+ echo "Test passed! Will use '${RSYSLOG_LIBFAKETIME}' library!"
+ export RSYSLOG_PRELOAD="${RSYSLOG_LIBFAKETIME}"
+ fi
+
+ # GMT-1 (POSIX TIME) is GMT+1 in "Human Time"
+ faketime_testtime=$(LD_PRELOAD="${RSYSLOG_LIBFAKETIME}" FAKETIME="2040-01-01 16:00:00" TZ=GMT-1 date +%s 2>/dev/null)
+ if [ ${faketime_testtime} -eq -1 ]; then
+ echo "Note: System is not year-2038 compliant"
+ RSYSLOG_TESTBENCH_Y2K38_INCOMPATIBLE="yes"
+ else
+ echo "Note: System is year-2038 compliant"
+ fi
+}
+
+rsyslog_testbench_require_y2k38_support() {
+ if [ -n "${RSYSLOG_TESTBENCH_Y2K38_INCOMPATIBLE}" ]; then
+ echo "Skipping further tests because system doesn't support year 2038 ..."
+ exit_test
+ exit 0
+ fi
+}
+
+rsyslog_testbench_preload_libfaketime
diff --git a/tests/fieldtest-udp.sh b/tests/fieldtest-udp.sh
new file mode 100755
index 0000000..30afc08
--- /dev/null
+++ b/tests/fieldtest-udp.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%msg:F,32:2%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: DROP_url_www.sina.com.cn:IN=eth1 OUT=eth0 SRC=192.168.10.78 DST=61.172.201.194 LEN=1182 TOS=0x00 PREC=0x00 TTL=63 ID=14368 DF PROTO=TCP SPT=33343 DPT=80 WINDOW=92 RES=0x00 ACK PSH URGP=0\""
+shutdown_when_empty
+wait_shutdown
+
+echo 'DROP_url_www.sina.com.cn:IN=eth1' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/fieldtest.sh b/tests/fieldtest.sh
new file mode 100755
index 0000000..d9d2b1a
--- /dev/null
+++ b/tests/fieldtest.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%msg:F,32:2%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: DROP_url_www.sina.com.cn:IN=eth1 OUT=eth0 SRC=192.168.10.78 DST=61.172.201.194 LEN=1182 TOS=0x00 PREC=0x00 TTL=63 ID=14368 DF PROTO=TCP SPT=33343 DPT=80 WINDOW=92 RES=0x00 ACK PSH URGP=0\""
+shutdown_when_empty
+wait_shutdown
+
+echo 'DROP_url_www.sina.com.cn:IN=eth1' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/func-substring-invld-startpos-vg.sh b/tests/func-substring-invld-startpos-vg.sh
new file mode 100755
index 0000000..cbd3e55
--- /dev/null
+++ b/tests/func-substring-invld-startpos-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/func-substring-invld-startpos.sh
diff --git a/tests/func-substring-invld-startpos.sh b/tests/func-substring-invld-startpos.sh
new file mode 100755
index 0000000..5f658e3
--- /dev/null
+++ b/tests/func-substring-invld-startpos.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# addd 2023-01-13 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="data:%$!my_struc_data%\n")
+
+set $!my_struc_data = substring($STRUCTURED-DATA, 2000, -3);
+local4.debug action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg_literal '<167>1 2003-03-01T01:00:00.000Z hostname1 sender - tag [tcpflood@32473 MSGNUM="0"] data'
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='data:'
+cmp_exact
+exit_test
diff --git a/tests/func-substring-large-endpos.sh b/tests/func-substring-large-endpos.sh
new file mode 100755
index 0000000..78d5d7d
--- /dev/null
+++ b/tests/func-substring-large-endpos.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# addd 2023-01-13 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!my_struc_data%\n")
+
+set $!my_struc_data = substring($STRUCTURED-DATA, 1, 99999999);
+local4.debug action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg_literal '<167>1 2003-03-01T01:00:00.000Z hostname1 sender - tag [tcpflood@32473 MSGNUM="0"] data'
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='tcpflood@32473 MSGNUM="0"]'
+cmp_exact
+exit_test
diff --git a/tests/func-substring-large-neg-endpos.sh b/tests/func-substring-large-neg-endpos.sh
new file mode 100755
index 0000000..23344f0
--- /dev/null
+++ b/tests/func-substring-large-neg-endpos.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# addd 2023-01-13 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="data:%$!my_struc_data%\n")
+
+set $!my_struc_data = substring($STRUCTURED-DATA, 1, -9999999);
+local4.debug action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg_literal '<167>1 2003-03-01T01:00:00.000Z hostname1 sender - tag [tcpflood@32473 MSGNUM="0"] data'
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='data:'
+cmp_exact
+exit_test
diff --git a/tests/func-substring-relative-endpos.sh b/tests/func-substring-relative-endpos.sh
new file mode 100755
index 0000000..43c6745
--- /dev/null
+++ b/tests/func-substring-relative-endpos.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# addd 2023-01-13 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!my_struc_data%\n")
+
+set $!my_struc_data = substring($STRUCTURED-DATA, 1, -2);
+local4.debug action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg_literal '<167>1 2003-03-01T01:00:00.000Z hostname1 sender - tag [tcpflood@32473 MSGNUM="0"] data'
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='tcpflood@32473 MSGNUM="0"'
+cmp_exact
+exit_test
diff --git a/tests/glbl-internalmsg_severity-debug-not_shown.sh b/tests/glbl-internalmsg_severity-debug-not_shown.sh
new file mode 100755
index 0000000..b3b3113
--- /dev/null
+++ b/tests/glbl-internalmsg_severity-debug-not_shown.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# check that info-severity messages are actually emitted; we use
+# lookup table as a simple sample to get such a message.
+# addd 2019-05-07 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl" reloadOnHUP="on")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+startup
+shutdown_when_empty
+wait_shutdown
+check_not_present "rsyslogd fully started up and initialized - begin actual processing"
+exit_test
diff --git a/tests/glbl-internalmsg_severity-debug-shown.sh b/tests/glbl-internalmsg_severity-debug-shown.sh
new file mode 100755
index 0000000..1231302
--- /dev/null
+++ b/tests/glbl-internalmsg_severity-debug-shown.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# check that info-severity messages are actually emitted; we use
+# lookup table as a simple sample to get such a message.
+# addd 2019-05-07 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(internalmsg.severity="debug")
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl" reloadOnHUP="on")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "rsyslogd fully started up and initialized - begin actual processing"
+exit_test
diff --git a/tests/glbl-internalmsg_severity-info-shown.sh b/tests/glbl-internalmsg_severity-info-shown.sh
new file mode 100755
index 0000000..265894f
--- /dev/null
+++ b/tests/glbl-internalmsg_severity-info-shown.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# check that info-severity messages are actually emitted; we use
+# lookup table as a simple sample to get such a message.
+# addd 2019-05-07 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(internalmsg.severity="info")
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl" reloadOnHUP="on")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "lookup table 'xlate' loaded from file"
+exit_test
diff --git a/tests/glbl-invld-param.sh b/tests/glbl-invld-param.sh
new file mode 100755
index 0000000..f9f4341
--- /dev/null
+++ b/tests/glbl-invld-param.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# make sure we do not abort on invalid parameter (we
+# once had this problem)
+# addd 2016-03-03 by RGerhards, released under ASL 2.0
+echo \[glbl-invld-param\]:
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(invalid="off")
+global(debug.unloadModules="invalid")
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+sleep 1
+shutdown_when_empty
+wait_shutdown
+# if we reach this point, we consider this a success.
+exit_test
diff --git a/tests/glbl-oversizeMsg-log-vg.sh b/tests/glbl-oversizeMsg-log-vg.sh
new file mode 100755
index 0000000..21878c5
--- /dev/null
+++ b/tests/glbl-oversizeMsg-log-vg.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# add 2018-05-03 by PascalWithopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+./have_relpSrvSetOversizeMode
+if [ $? -eq 1 ]; then
+ echo "imrelp parameter oversizeMode not available. Test stopped"
+ exit 77
+fi;
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+global(maxMessageSize="230"
+ oversizemsg.errorfile=`echo $RSYSLOG2_OUT_LOG`)
+
+
+input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="300")
+
+template(name="outfmt" type="string" string="%rawmsg%\n")
+action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+# TODO: add tcpflood option to specific EXACT test message size!
+startup_vg
+tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m1 -d 240
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown_vg
+check_exit_vg
+grep "rawmsg.*<167>Mar 1 01:00:00 172.20.245.8 tag msgnum:00000000:240:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.*input.*imrelp" ${RSYSLOG2_OUT_LOG} > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message not found. ${RSYSLOG2_OUT_LOG} is:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi
+
+
+exit_test
diff --git a/tests/glbl-oversizeMsg-log.sh b/tests/glbl-oversizeMsg-log.sh
new file mode 100755
index 0000000..f5568ab
--- /dev/null
+++ b/tests/glbl-oversizeMsg-log.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# add 2018-05-03 by PascalWithopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+./have_relpSrvSetOversizeMode
+if [ $? -eq 1 ]; then
+ echo "imrelp parameter oversizeMode not available. Test stopped"
+ exit 77
+fi;
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+global(maxMessageSize="230"
+ oversizemsg.errorfile=`echo $RSYSLOG2_OUT_LOG`)
+
+
+input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="300")
+
+template(name="outfmt" type="string" string="%rawmsg%\n")
+action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+# TODO: add tcpflood option to specific EXACT test message size!
+startup
+tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m1 -d 240
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+grep "rawmsg.*<167>Mar 1 01:00:00 172.20.245.8 tag msgnum:00000000:240:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.*input.*imrelp" ${RSYSLOG2_OUT_LOG} > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message not found. ${RSYSLOG2_OUT_LOG} is:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi
+
+
+exit_test
diff --git a/tests/glbl-oversizeMsg-split.sh b/tests/glbl-oversizeMsg-split.sh
new file mode 100755
index 0000000..010ab21
--- /dev/null
+++ b/tests/glbl-oversizeMsg-split.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# add 2018-05-03 by PascalWithopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+./have_relpSrvSetOversizeMode
+if [ $? -eq 1 ]; then
+ echo "imrelp parameter oversizeMode not available. Test stopped"
+ exit 77
+fi;
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+global(maxMessageSize="230"
+ oversizemsg.input.mode="split")
+
+
+input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="300")
+
+template(name="outfmt" type="string" string="%rawmsg%\n")
+action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+# TODO: add tcpflood option to specific EXACT test message size!
+startup
+tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m1 -d 240
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+# We need the ^-sign to symbolize the beginning and the $-sign to symbolize the end
+# because otherwise we won't know if it was truncated at the right length.
+#First part of message is checked
+grep "^<167>Mar 1 01:00:00 172.20.245.8 tag msgnum:00000000:240:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+#Split part of message is checked
+grep "^XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+#Error message is checked
+grep "message too long.*begin of message is:" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+
+exit_test
diff --git a/tests/glbl-oversizeMsg-truncate-imfile.sh b/tests/glbl-oversizeMsg-truncate-imfile.sh
new file mode 100755
index 0000000..d281c6a
--- /dev/null
+++ b/tests/glbl-oversizeMsg-truncate-imfile.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# add 2018-05-02 by PascalWithopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+./have_relpSrvSetOversizeMode
+if [ $? -eq 1 ]; then
+ echo "imrelp parameter oversizeMode not available. Test stopped"
+ exit 77
+fi;
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+global(maxMessageSize="230"
+ oversizemsg.input.mode="truncate")
+
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" tag="tag:")
+
+template(name="outfmt" type="string" string="%rawmsg%\n")
+action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+echo '<167>Mar 1 01:00:00 172.20.245.8 tag msgnum:00000000:240:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' > $RSYSLOG_DYNNAME.input
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+# We need the ^-sign to symbolize the beginning and the $-sign to symbolize the end
+# because otherwise we won't know if it was truncated at the right length.
+grep "^<167>Mar 1 01:00:00 172.20.245.8 tag msgnum:00000000:240:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$" $RSYSLOG_OUT_LOG #> /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+grep "message too long.*begin of message is:" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+
+exit_test
diff --git a/tests/glbl-oversizeMsg-truncate.sh b/tests/glbl-oversizeMsg-truncate.sh
new file mode 100755
index 0000000..9b3fb47
--- /dev/null
+++ b/tests/glbl-oversizeMsg-truncate.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# add 2018-05-02 by PascalWithopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+./have_relpSrvSetOversizeMode
+if [ $? -eq 1 ]; then
+ echo "imrelp parameter oversizeMode not available. Test stopped"
+ exit 77
+fi;
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+global(maxMessageSize="230")
+
+
+input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="300")
+
+template(name="outfmt" type="string" string="%rawmsg%\n")
+action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+# TODO: add tcpflood option to specific EXACT test message size!
+startup
+tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m1 -d 240
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+# We need the ^-sign to symbolize the beginning and the $-sign to symbolize the end
+# because otherwise we won't know if it was truncated at the right length.
+grep "^<167>Mar 1 01:00:00 172.20.245.8 tag msgnum:00000000:240:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+grep "message too long.*begin of message is:" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+
+exit_test
diff --git a/tests/glbl-ruleset-queue-defaults.sh b/tests/glbl-ruleset-queue-defaults.sh
new file mode 100755
index 0000000..fc625cf
--- /dev/null
+++ b/tests/glbl-ruleset-queue-defaults.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# check that global ruleset queue defaults can be specified. However,
+# we do not tests that they actually work - that's quite hard to
+# do reliably.
+# addd 2019-05-09 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global( default.ruleset.queue.timeoutshutdown="1000"
+ default.ruleset.queue.timeoutactioncompletion="1000"
+ default.ruleset.queue.timeoutenqueue="1000"
+ default.ruleset.queue.timeoutworkerthreadshutdown="1000"
+ )
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+startup
+shutdown_when_empty
+wait_shutdown
+check_not_present 'parameter.*not known'
+exit_test
diff --git a/tests/glbl-umask.sh b/tests/glbl-umask.sh
new file mode 100755
index 0000000..dcea2a1
--- /dev/null
+++ b/tests/glbl-umask.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# addd 2017-03-06 by RGerhards, released under ASL 2.0
+
+# Note: we need to inject a somewhat larger number of messages in order
+# to ensure that we receive some messages in the actual output file,
+# as batching can (validly) cause a larger loss in the non-writable
+# file
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(umask="0077")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" {
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+
+if [ `ls -l $RSYSLOG_OUT_LOG|$RS_HEADCMD -c 10 ` != "-rw-------" ]; then
+ echo "invalid file permission (umask), $RSYSLOG_OUT_LOG has:"
+ ls -l $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+exit_test
diff --git a/tests/glbl-unloadmodules.sh b/tests/glbl-unloadmodules.sh
new file mode 100755
index 0000000..9b006fd
--- /dev/null
+++ b/tests/glbl-unloadmodules.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# we only test if the parameter is accepted - we cannot
+# reliably deduce from the outside if it really worked.
+# addd 2016-03-03 by RGerhards, released under ASL 2.0
+echo \[glbl-unloadmodules\]:
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(debug.unloadModules="off")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+sleep 1
+shutdown_when_empty
+wait_shutdown
+# to check for support, we check if an error message has
+# been recorded, which would bear the name of our option.
+# if it is not recorded, we assume all is well. Not perfect,
+# but works good enough.
+grep -i "unloadModules" < $RSYSLOG_OUT_LOG
+if [ ! $? -eq 1 ]; then
+ echo "parameter name in output, assuming error message:"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi;
+exit_test
diff --git a/tests/glbl_setenv.sh b/tests/glbl_setenv.sh
new file mode 100755
index 0000000..1387bbd
--- /dev/null
+++ b/tests/glbl_setenv.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(environment="http_proxy=http://127.0.0.1")
+
+set $!prx = getenv("http_proxy");
+
+template(name="outfmt" type="string" string="%$!prx%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+injectmsg 0 1
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+echo 'http://127.0.0.1' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid content seen, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/glbl_setenv_2_vars.sh b/tests/glbl_setenv_2_vars.sh
new file mode 100755
index 0000000..e472c73
--- /dev/null
+++ b/tests/glbl_setenv_2_vars.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(environment=["http_proxy=http://127.0.0.1", "SECOND=OK OK"])
+
+set $!prx = getenv("http_proxy");
+set $!second = getenv("SECOND");
+
+template(name="outfmt" type="string" string="%$!prx%, %$!second%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+injectmsg 0 1
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+echo 'http://127.0.0.1, OK OK' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid content seen, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/glbl_setenv_err.sh b/tests/glbl_setenv_err.sh
new file mode 100755
index 0000000..0712ee5
--- /dev/null
+++ b/tests/glbl_setenv_err.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# env var is missing equal sign and MUST trigger parsing error!
+global(environment="http_proxy ERROR")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+injectmsg 0 1
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+grep "http_proxy ERROR" < $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo
+ echo "MESSAGE INDICATING ERROR ON ENVIRONMENT VARIABLE IS MISSING:"
+ echo
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/glbl_setenv_err_too_long.sh b/tests/glbl_setenv_err_too_long.sh
new file mode 100755
index 0000000..ad994ac
--- /dev/null
+++ b/tests/glbl_setenv_err_too_long.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# name is 400 chars long --> too long
+global(environment="NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN=400")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+injectmsg 0 1
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+grep "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN" < $RSYSLOG_OUT_LOG > /dev/null
+if [ ! $? -eq 0 ]; then
+ echo
+ echo "MESSAGE INDICATING ERROR ON ENVIRONMENT VARIABLE IS MISSING:"
+ echo
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/global_vars.sh b/tests/global_vars.sh
new file mode 100755
index 0000000..1d66566
--- /dev/null
+++ b/tests/global_vars.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Test for global variables
+# added 2013-11-18 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[global_vars.sh\]: testing global variable support
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MainMsgQueueTimeoutShutdown 10000
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%$/msgnum%\n")
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) /* trick to use relative path names! */
+
+if $/msgnum == "" then
+ set $/msgnum = 0;
+
+if $msg contains "msgnum:" then {
+ action(type="omfile" dynaFile="dynfile" template="outfmt")
+ set $/msgnum = $/msgnum + 1;
+}
+'
+startup
+
+# 40000 messages should be enough
+injectmsg 0 40000
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 39999
+exit_test
diff --git a/tests/gzipwr_flushInterval.sh b/tests/gzipwr_flushInterval.sh
new file mode 100755
index 0000000..c5df022
--- /dev/null
+++ b/tests/gzipwr_flushInterval.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test currently does not work on FreeBSD"
+export NUMMESSAGES=5000 #even number!
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+export SEQ_CHECK_FILE=$RSYSLOG_OUT_LOG.gz
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ zipLevel="6" ioBufferSize="256k"
+ flushOnTXEnd="off" flushInterval="1"
+ asyncWriting="on"
+ file="'$RSYSLOG_OUT_LOG'.gz")
+'
+startup
+tcpflood -m$((NUMMESSAGES / 2)) -P129
+./msleep 5000 #wait for flush
+seq_check 0 2499
+tcpflood -i$((NUMMESSAGES / 2)) -m$((NUMMESSAGES / 2)) -P129
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/gzipwr_flushOnTXEnd.sh b/tests/gzipwr_flushOnTXEnd.sh
new file mode 100755
index 0000000..c396be3
--- /dev/null
+++ b/tests/gzipwr_flushOnTXEnd.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test currently does not work on FreeBSD"
+export NUMMESSAGES=5000 # MUST be an even number
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" { action(type="omfile" template="outfmt"
+ zipLevel="6" ioBufferSize="256k"
+ flushOnTXEnd="on"
+ asyncWriting="on"
+ file="'$RSYSLOG_OUT_LOG'")
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.countlog")
+ }
+'
+startup
+tcpflood -m$((NUMMESSAGES / 2)) -P129
+wait_queueempty
+echo test 1
+wait_file_lines "$RSYSLOG_DYNNAME.countlog" $((NUMMESSAGES / 2 ))
+gzip_seq_check 0 $((NUMMESSAGES / 2 - 1))
+tcpflood -i$((NUMMESSAGES / 2)) -m$((NUMMESSAGES / 2)) -P129
+echo test 2
+wait_file_lines "$RSYSLOG_DYNNAME.countlog" $NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+gzip_seq_check
+exit_test
diff --git a/tests/gzipwr_hup-vg.sh b/tests/gzipwr_hup-vg.sh
new file mode 100755
index 0000000..5db04e0
--- /dev/null
+++ b/tests/gzipwr_hup-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export NUMMESSAGES=200000 # reduce for slower valgrind run
+source ${srcdir:-.}/gzipwr_hup.sh
diff --git a/tests/gzipwr_hup.sh b/tests/gzipwr_hup.sh
new file mode 100755
index 0000000..ffca610
--- /dev/null
+++ b/tests/gzipwr_hup.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# Written 2019-06-12 by Rainer Gerhards
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=${NUMMESSAGES:-2000000}
+export COUNT_FILE_IS_ZIPPED=yes
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+export TB_TEST_TIMEOUT=180 # test is slow due to large number of messages
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'")
+
+
+
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ zipLevel="9" ioBufferSize="16" flushOnTXEnd="on"
+ dynafile="dynfile")
+'
+startup
+./tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES & # TCPFlood needs to run async!
+BGPROCESS=$!
+for i in $(seq 1 20); do
+ printf '\nsending HUP %d\n' $i
+ issue_HUP --sleep 100
+done
+wait $BGPROCESS
+shutdown_when_empty
+wait_shutdown
+gzip_seq_check
+exit_test
diff --git a/tests/gzipwr_hup_multi_file.sh b/tests/gzipwr_hup_multi_file.sh
new file mode 100755
index 0000000..3083820
--- /dev/null
+++ b/tests/gzipwr_hup_multi_file.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# Written 2019-06-12 by Rainer Gerhards
+export TEST_MAX_RUNTIME=7200
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100000
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+main_queue(queue.workerThreads="10" queue.workerThreadMinimumMessages="200")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'.%$/file%")
+
+
+
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ zipLevel="9" ioBufferSize="16" flushOnTXEnd="on"
+ dynafile="dynfile" dynaFileCacheSize="5"
+ asyncWriting="on")
+
+if $msg contains "msgnum" then {
+ set $/file = cnum($/file) + 1;
+ if $/file >= 10 then {
+ set $/file = 0;
+ }
+}
+'
+startup
+./tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES & # TCPFlood needs to run async!
+for i in $(seq 0 20); do
+ printf '\nsending HUP %d\n' $i
+ issue_HUP
+ ./msleep 10
+done
+shutdown_when_empty
+wait_shutdown
+ls -l ${RSYSLOG_OUT_LOG}.*
+for f in "${RSYSLOG_OUT_LOG}".*; do
+ echo unzipping $f
+ gunzip < "$f" >> $RSYSLOG_OUT_LOG
+done
+seq_check
+exit_test
diff --git a/tests/gzipwr_hup_single_file.sh b/tests/gzipwr_hup_single_file.sh
new file mode 100755
index 0000000..e1308b2
--- /dev/null
+++ b/tests/gzipwr_hup_single_file.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# Written 2019-06-12 by Rainer Gerhards
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+main_queue(queue.workerThreads="10" queue.workerThreadMinimumMessages="200")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'")
+
+
+
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ zipLevel="9" ioBufferSize="16" flushOnTXEnd="on"
+ dynafile="dynfile" dynaFileCacheSize="5"
+ asyncWriting="on")
+
+if $msg contains "msgnum" then {
+ set $/file = cnum($/file) + 1;
+ if $/file >= 10 then {
+ set $/file = 0;
+ }
+}
+'
+startup
+./tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES & # TCPFlood needs to run async!
+for i in $(seq 0 20); do
+ ./msleep 10
+ printf '\nsending HUP %d\n' $i
+ issue_HUP
+done
+shutdown_when_empty
+wait_shutdown
+gzip_seq_check
+exit_test
diff --git a/tests/gzipwr_large.sh b/tests/gzipwr_large.sh
new file mode 100755
index 0000000..69f93ae
--- /dev/null
+++ b/tests/gzipwr_large.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# This tests writing large data records in gzip mode. We use up to 10K
+# record size.
+#
+# added 2010-03-10 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=4000
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+export SEQ_CHECK_FILE=$RSYSLOG_OUT_LOG.gz
+add_conf '
+$MaxMessageSize 10k
+$MainMsgQueueTimeoutShutdown 10000
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+local0.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'.gz" template="outfmt"
+ zipLevel="6" veryRobustZip="on")
+'
+# rgerhards, 2019-08-14: Note: veryRobustZip may need to be "on". Do this if the test
+# still prematurely terminates. In that case it is likely that gunzip got confused
+# by the missing zip close record. My initial testing shows that while gunzip emits an
+# error message, everything is properly extracted. Only stressed CI runs will show how
+# it works in reality.
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -m$NUMMESSAGES -r -d10000 -P129
+shutdown_when_empty
+wait_shutdown
+seq_check 0 $((NUMMESSAGES - 1)) -E
+exit_test
diff --git a/tests/gzipwr_large_dynfile.sh b/tests/gzipwr_large_dynfile.sh
new file mode 100755
index 0000000..6cf5eb6
--- /dev/null
+++ b/tests/gzipwr_large_dynfile.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# This tests writing large data records in gzip mode. We also write it to
+# 5 different dynafiles, with a dynafile cache size set to 4. So this stresses
+# both the input side, as well as zip writing, async writing and the dynafile
+# cache logic.
+#
+# This test is a bit timing-dependent on the tcp reception side, so if it fails
+# one may look into the timing first. The main issue is that the testbench
+# currently has no good way to know if the tcp receiver is finished. This is NOT
+# a problem in rsyslogd, but only of the testbench.
+#
+# Note that we do not yet have sufficient support for dynafiles in diag.sh,
+# so we mangle some files here manually.
+#
+# added 2010-03-10 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "FIXME: this test does not work on Solaris because of what looks like a BUG! It is just disabled here so that we can gain the benefits of a better test on other platforms. Bug on solaris must be addressed"
+combine_files() {
+ gunzip -c < $RSYSLOG_DYNNAME.out.0.log > $RSYSLOG_OUT_LOG
+ gunzip -c < $RSYSLOG_DYNNAME.out.1.log >> $RSYSLOG_OUT_LOG
+ gunzip -c < $RSYSLOG_DYNNAME.out.2.log >> $RSYSLOG_OUT_LOG
+ gunzip -c < $RSYSLOG_DYNNAME.out.3.log >> $RSYSLOG_OUT_LOG
+ gunzip -c < $RSYSLOG_DYNNAME.out.4.log >> $RSYSLOG_OUT_LOG
+}
+export NUMMESSAGES=4000
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+export PRE_SEQ_CHECK_FUNC=combine_files
+export SEQ_CHECK_FILE=$RSYSLOG_OUT_LOG
+export SEQ_CHECK_OPTIONS=-E
+generate_conf
+add_conf '
+global(MaxMessageSize="10k")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:3%,%msg:F,58:4%,%msg:F,58:5%\n"
+$template dynfile,"'$RSYSLOG_DYNNAME'.out.%msg:F,58:2%.log" # use multiple dynafiles
+local0.* action(type="omfile" template="outfmt"
+ zipLevel="6" ioBufferSize="256k" veryRobustZip="on"
+ flushOnTXEnd="off" flushInterval="1"
+ asyncWriting="on" dynaFileCacheSize="4"
+ dynafile="dynfile")
+'
+startup
+# send messages of 10.000bytes plus header max, randomized
+tcpflood -m$NUMMESSAGES -r -d10000 -P129 -f5
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/gzipwr_rscript.sh b/tests/gzipwr_rscript.sh
new file mode 100755
index 0000000..4868c7b
--- /dev/null
+++ b/tests/gzipwr_rscript.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ zipLevel="6" ioBufferSize="256k" flushOnTXEnd="off"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m2500 -P129
+tcpflood -i2500 -m2500 -P129
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+gzip_seq_check 0 4999
+exit_test
diff --git a/tests/have_relpEngineSetTLSLibByName.c b/tests/have_relpEngineSetTLSLibByName.c
new file mode 100644
index 0000000..f8e5d88
--- /dev/null
+++ b/tests/have_relpEngineSetTLSLibByName.c
@@ -0,0 +1,10 @@
+#include "config.h"
+
+int main(int argc __attribute__((unused)), char *argv[]__attribute__((unused)))
+{
+#if defined(HAVE_RELPENGINESETTLSLIBBYNAME)
+ return 0;
+#else
+ return 1;
+#endif
+}
diff --git a/tests/have_relpSrvSetOversizeMode.c b/tests/have_relpSrvSetOversizeMode.c
new file mode 100644
index 0000000..0c76ab3
--- /dev/null
+++ b/tests/have_relpSrvSetOversizeMode.c
@@ -0,0 +1,10 @@
+#include "config.h"
+
+int main(int argc __attribute__((unused)), char *argv[]__attribute__((unused)))
+{
+#ifdef HAVE_RELPSRVSETOVERSIZEMODE
+ return 0;
+#else
+ return 1;
+#endif
+}
diff --git a/tests/have_relpSrvSetTlsConfigCmd.c b/tests/have_relpSrvSetTlsConfigCmd.c
new file mode 100644
index 0000000..fef068c
--- /dev/null
+++ b/tests/have_relpSrvSetTlsConfigCmd.c
@@ -0,0 +1,10 @@
+#include "config.h"
+
+int main(int argc __attribute__((unused)), char *argv[]__attribute__((unused)))
+{
+#if defined(HAVE_RELPENGINESETTLSCFGCMD)
+ return 0;
+#else
+ return 1;
+#endif
+}
diff --git a/tests/hostname-with-slash-dflt-invld.sh b/tests/hostname-with-slash-dflt-invld.sh
new file mode 100755
index 0000000..206489f
--- /dev/null
+++ b/tests/hostname-with-slash-dflt-invld.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# addd 2016-07-11 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+setvar_RS_HOSTNAME
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="string" string="%hostname%") # no LF, as HOSTNAME file also does not have it!
+
+local4.debug action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+echo '<167>Mar 6 16:57:54 hostname1/hostname2 test: msgnum:0' > $RSYSLOG_DYNNAME.input
+tcpflood -B -I $RSYSLOG_DYNNAME.input
+shutdown_when_empty
+wait_shutdown
+printf '%s' "$RS_HOSTNAME" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid hostname generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ echo
+ echo "expected was:"
+ printf '%s\n' "$RS_HOSTNAME"
+ echo
+ error_exit 1
+fi;
+exit_test
diff --git a/tests/hostname-with-slash-dflt-slash-valid.sh b/tests/hostname-with-slash-dflt-slash-valid.sh
new file mode 100755
index 0000000..6305d7d
--- /dev/null
+++ b/tests/hostname-with-slash-dflt-slash-valid.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# addd 2016-07-11 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="string" string="%hostname%\n")
+
+# note: we use the default parser chain, which includes RFC5424 and that parser
+# should be selected AND detect the hostname with slashes as valid.
+local4.debug action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+echo '<167>1 2003-03-01T01:00:00.000Z hostname1/hostname2 tcpflood - tag [tcpflood@32473 MSGNUM="0"] data' > $RSYSLOG_DYNNAME.input
+tcpflood -B -I $RSYSLOG_DYNNAME.input
+shutdown_when_empty
+wait_shutdown
+echo "hostname1/hostname2" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid hostname generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+exit_test
diff --git a/tests/hostname-with-slash-pmrfc3164.sh b/tests/hostname-with-slash-pmrfc3164.sh
new file mode 100755
index 0000000..3d1ad21
--- /dev/null
+++ b/tests/hostname-with-slash-pmrfc3164.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# addd 2016-07-11 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="string" string="%hostname%\n")
+
+parser(name="pmrfc3164.hostname_with_slashes" type="pmrfc3164" permit.slashesinhostname="on")
+$rulesetparser pmrfc3164.hostname_with_slashes
+local4.debug action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+echo '<167>Mar 6 16:57:54 hostname1/hostname2 test: msgnum:0' > $RSYSLOG_DYNNAME.input
+tcpflood -B -I $RSYSLOG_DYNNAME.input
+shutdown_when_empty
+wait_shutdown
+echo "hostname1/hostname2" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid hostname generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+exit_test
diff --git a/tests/hostname-with-slash-pmrfc5424.sh b/tests/hostname-with-slash-pmrfc5424.sh
new file mode 100755
index 0000000..6ffa77f
--- /dev/null
+++ b/tests/hostname-with-slash-pmrfc5424.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# addd 2016-07-11 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="string" string="%hostname%\n")
+
+$rulesetparser rsyslog.rfc5424
+local4.debug action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+echo '<167>1 2003-03-01T01:00:00.000Z hostname1/hostname2 tcpflood - tag [tcpflood@32473 MSGNUM="0"] data' > $RSYSLOG_DYNNAME.input
+tcpflood -B -I $RSYSLOG_DYNNAME.input
+shutdown_when_empty
+wait_shutdown
+echo "hostname1/hostname2" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid hostname generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+exit_test
diff --git a/tests/imbatchreport_delete_structdata.sh b/tests/imbatchreport_delete_structdata.sh
new file mode 100755
index 0000000..607b054
--- /dev/null
+++ b/tests/imbatchreport_delete_structdata.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# 804/805 fail/sent with space dedup
+global(maxmessagesize="820")
+module(load="../contrib/imbatchreport/.libs/imbatchreport" pollinginterval="1")
+global(localhostname="server")
+input(type="imbatchreport" ruleset="ruleset" tag="batch"
+ severity="info" facility="local0"
+ reports="./'$RSYSLOG_DYNNAME'*.done" deduplicatespace="on"
+ programkey="KSH" timestampkey="START"
+ delete=".done$ .rejected"
+ )
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="RSYSLOG_SyslogProtocol23Format")
+}
+'
+{
+ echo '164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)'
+ echo '164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree'
+ echo '164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)'
+ echo '164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree'
+ echo '164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)'
+ echo '164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1'
+ echo ' [START=1552143924 KSH="MYBATCH.sh"'
+ echo ' DURATION=120] '
+} > $RSYSLOG_DYNNAME.dsd.done
+echo "Batch report to consume ${RSYSLOG_DYNNAME}.dsd.done for 2019-03-09T15:05:24"
+startup
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='<134>1 2019-03-09T15:05:24.000000+00:00 server MYBATCH.sh - - [START=1552143924 KSH="MYBATCH.sh" DURATION=120] 164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)\n164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree\n164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)\n164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree\n164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)\n164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1'
+cmp_exact
+if [ -e $RSYSLOG_DYNNAME.dsd.sent ] || [ -e $RSYSLOG_DYNNAME.dsd.rejected ] || [ -e $RSYSLOG_DYNNAME.dsd.done ]; then
+ echo "The batch report was not deleted"
+ ls $RSYSLOG_DYNNAME*
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imbatchreport_delete_success.sh b/tests/imbatchreport_delete_success.sh
new file mode 100755
index 0000000..f650e10
--- /dev/null
+++ b/tests/imbatchreport_delete_success.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# 804/805 fail/sent with space dedup
+global(maxmessagesize="820")
+module(load="../contrib/imbatchreport/.libs/imbatchreport" pollinginterval="1")
+global(localhostname="server")
+input(type="imbatchreport" ruleset="ruleset" tag="batch"
+ severity="info" facility="local0"
+ reports="./'$RSYSLOG_DYNNAME'*.done" deduplicatespace="on"
+ programkey="KSH" timestampkey="START"
+ delete=".done$ .rejected"
+ )
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="RSYSLOG_SyslogProtocol23Format")
+}
+'
+{
+ echo '164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)'
+ echo '164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree'
+ echo '164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)'
+ echo '164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree'
+ echo '164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)'
+ echo '164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1'
+} > $RSYSLOG_DYNNAME.dsu.done
+case $(uname) in
+ FreeBSD)
+ datelog=$(date -r $(stat -f %m $RSYSLOG_DYNNAME.dsu.done) "+%Y-%m-%dT%H:%M:%S")
+ ;;
+ *)
+ datelog=$(date "+%Y-%m-%dT%H:%M:%S" -ud @$(stat -c "%Y" $RSYSLOG_DYNNAME.dsu.done))
+ ;;
+esac
+echo "Batch report to consume ${RSYSLOG_DYNNAME}.dsu.done for ${datelog}"
+startup
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='<134>1 '${datelog}'.000000+00:00 server batch - - - 164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)\n164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree\n164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)\n164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree\n164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)\n164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1'
+cmp_exact
+if [ -e $RSYSLOG_DYNNAME.dsu.sent ] || [ -e $RSYSLOG_DYNNAME.dsu.rejected ] || [ -e $RSYSLOG_DYNNAME.dsu.done ]; then
+ echo "The batch report was not deleted"
+ ls $RSYSLOG_DYNNAME*
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imbatchreport_delete_toolarge.sh b/tests/imbatchreport_delete_toolarge.sh
new file mode 100755
index 0000000..a0aa35c
--- /dev/null
+++ b/tests/imbatchreport_delete_toolarge.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# 804/805 fail/sent with space dedup
+global(maxmessagesize="800")
+module(load="../contrib/imbatchreport/.libs/imbatchreport" pollinginterval="1")
+global(localhostname="server")
+input(type="imbatchreport" ruleset="ruleset" tag="batch"
+ severity="info" facility="local0"
+ reports="./'$RSYSLOG_DYNNAME'*.done" deduplicatespace="on"
+ programkey="KSH" timestampkey="START"
+ delete=".done$ .rejected"
+ )
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="RSYSLOG_SyslogProtocol23Format")
+}
+'
+{
+ echo '164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)'
+ echo '164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree'
+ echo '164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)'
+ echo '164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree'
+ echo '164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)'
+ echo '164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1'
+} > $RSYSLOG_DYNNAME.dtl.done
+case $(uname) in
+ FreeBSD)
+ datelog=$(date -ur $(stat -f %m $RSYSLOG_DYNNAME.dtl.done) "+%Y-%m-%dT%H:%M:%S")
+ ;;
+ *)
+ datelog=$(date -ud @$(stat -c "%Y" $RSYSLOG_DYNNAME.dtl.done) "+%Y-%m-%dT%H:%M:%S")
+ ;;
+esac
+echo "Batch report to consume ${RSYSLOG_DYNNAME}.dtl.done for ${datelog}"
+startup
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='<134>1 '${datelog}'.000000+00:00 server batch - - - File too large : ./'${RSYSLOG_DYNNAME}'.dtl.done'
+cmp_exact
+if [ -e $RSYSLOG_DYNNAME.dtl.done ] || [ -e $RSYSLOG_DYNNAME.dtl.sent ] || [ ! -e $RSYSLOG_DYNNAME.dtl.rejected ]; then
+ echo "The batch report could not be renamed to rejected"
+ ls $RSYSLOG_DYNNAME*
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_delete_params.sh b/tests/imbatchreport_errmsg_delete_params.sh
new file mode 100755
index 0000000..f4168c3
--- /dev/null
+++ b/tests/imbatchreport_errmsg_delete_params.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+input(type="imbatchreport" tag="t" reports="*.done" delete=".done$")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "'delete' must specify TWO parameters separated by spaces or tabs"
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_glob_dir_fake.sh b/tests/imbatchreport_errmsg_glob_dir_fake.sh
new file mode 100755
index 0000000..bd9fc5e
--- /dev/null
+++ b/tests/imbatchreport_errmsg_glob_dir_fake.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+
+input(type="imbatchreport" tag="t" rename=".done$ .s .r.done" reports="fake/*.done")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "Configured directory can not be stated"
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_glob_dir_not_dir.sh b/tests/imbatchreport_errmsg_glob_dir_not_dir.sh
new file mode 100755
index 0000000..77e6914
--- /dev/null
+++ b/tests/imbatchreport_errmsg_glob_dir_not_dir.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+input(type="imbatchreport" tag="t" rename=".done$ .s .r.done" reports="'$RSYSLOG_DYNNAME'_.conf/*.done")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "Configured directory is NOT a directory"
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_glob_not_regular.sh b/tests/imbatchreport_errmsg_glob_not_regular.sh
new file mode 100755
index 0000000..50bdb94
--- /dev/null
+++ b/tests/imbatchreport_errmsg_glob_not_regular.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+input(type="imbatchreport" tag="t" rename=".spool$ .s .r.done" reports="'$RSYSLOG_DYNNAME'.spool")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "Configured report is not a glob or a regular file"
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_no_params-vg.sh b/tests/imbatchreport_errmsg_no_params-vg.sh
new file mode 100755
index 0000000..17f6113
--- /dev/null
+++ b/tests/imbatchreport_errmsg_no_params-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imbatchreport_errmsg_no_params.sh
diff --git a/tests/imbatchreport_errmsg_no_params.sh b/tests/imbatchreport_errmsg_no_params.sh
new file mode 100755
index 0000000..7104216
--- /dev/null
+++ b/tests/imbatchreport_errmsg_no_params.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+
+input(type="imbatchreport")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter 'reports' required but not specified"
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_not_supported1.sh b/tests/imbatchreport_errmsg_not_supported1.sh
new file mode 100755
index 0000000..86b7a10
--- /dev/null
+++ b/tests/imbatchreport_errmsg_not_supported1.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+input(type="imbatchreport" tag="t" ruleset="r" delete=".done$ .r" rename=".done$ .s .r" reports="*.*")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "'rename' and 'delete' are exclusive"
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_not_supported2.sh b/tests/imbatchreport_errmsg_not_supported2.sh
new file mode 100755
index 0000000..7e8f060
--- /dev/null
+++ b/tests/imbatchreport_errmsg_not_supported2.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+input(type="imbatchreport" tag="t" ruleset="r" rename=".done$ .s .r" delete=".done$ .r" reports="*.*")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "'rename' and 'delete' are exclusive"
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_not_supported3.sh b/tests/imbatchreport_errmsg_not_supported3.sh
new file mode 100755
index 0000000..2a3d3ac
--- /dev/null
+++ b/tests/imbatchreport_errmsg_not_supported3.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+input(type="imbatchreport" tag="t" reports="*.done")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "either 'rename' or 'delete' must be set"
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_regex.match.reject.sh b/tests/imbatchreport_errmsg_regex.match.reject.sh
new file mode 100755
index 0000000..a64e620
--- /dev/null
+++ b/tests/imbatchreport_errmsg_regex.match.reject.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+
+input(type="imbatchreport" tag="t" rename=".done$ .s .r.done" reports="./*.done")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "Reject renaming leaves files in glob scope: Instance ignored to avoid loops."
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_regex.match.rename.sh b/tests/imbatchreport_errmsg_regex.match.rename.sh
new file mode 100755
index 0000000..5ec40ac
--- /dev/null
+++ b/tests/imbatchreport_errmsg_regex.match.rename.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+
+input(type="imbatchreport" tag="t" rename=".done$ .s.done .r" reports="./*.done")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "Normal renaming leaves files in glob scope: Instance ignored to avoid loops."
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_regex.nomatch.sh b/tests/imbatchreport_errmsg_regex.nomatch.sh
new file mode 100755
index 0000000..5461c70
--- /dev/null
+++ b/tests/imbatchreport_errmsg_regex.nomatch.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+
+input(type="imbatchreport" tag="t" rename=".done$ .s .r" reports="./*.bad")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "Regex does not match globed filenames: Instance ignored to avoid loops."
+
+exit_test
diff --git a/tests/imbatchreport_errmsg_rename_params.sh b/tests/imbatchreport_errmsg_rename_params.sh
new file mode 100755
index 0000000..a5fc9b4
--- /dev/null
+++ b/tests/imbatchreport_errmsg_rename_params.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imbatchreport/.libs/imbatchreport")
+input(type="imbatchreport" tag="t" reports="*.done" rename=".done$ - ")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "'rename' must specify THREE parameters separated by spaces or tabs"
+
+exit_test
diff --git a/tests/imbatchreport_rename_success.sh b/tests/imbatchreport_rename_success.sh
new file mode 100755
index 0000000..1ce996a
--- /dev/null
+++ b/tests/imbatchreport_rename_success.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# 804/805 fail/sent with space dedup
+global(maxmessagesize="820")
+module(load="../contrib/imbatchreport/.libs/imbatchreport" pollinginterval="1")
+global(localhostname="server")
+input(type="imbatchreport" ruleset="ruleset" tag="batch"
+ severity="info" facility="local0"
+ reports="./'$RSYSLOG_DYNNAME'*.done" deduplicatespace="on"
+ programkey="KSH" timestampkey="START"
+ rename=".done$ .sent .rejected"
+ )
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="RSYSLOG_SyslogProtocol23Format")
+}
+'
+{
+ echo '164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)'
+ echo '164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree'
+ echo '164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)'
+ echo '164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree'
+ echo '164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)'
+ echo '164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1'
+} > $RSYSLOG_DYNNAME.rsu.done
+case $(uname) in
+ FreeBSD)
+ datelog=$(date -ur $(stat -f %m $RSYSLOG_DYNNAME.rsu.done) "+%Y-%m-%dT%H:%M:%S")
+ ;;
+ *)
+ datelog=$(date "+%Y-%m-%dT%H:%M:%S" -ud @$(stat -c "%Y" $RSYSLOG_DYNNAME.rsu.done))
+ ;;
+esac
+echo "Batch report to consume ${RSYSLOG_DYNNAME}.rsu.done for ${datelog}"
+startup
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='<134>1 '${datelog}'.000000+00:00 server batch - - - 164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)\n164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree\n164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)\n164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree\n164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)\n164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1'
+cmp_exact
+if [ -e $RSYSLOG_DYNNAME.rsu.done ] || [ -e $RSYSLOG_DYNNAME.rsu.rejected ] || [ ! -e $RSYSLOG_DYNNAME.rsu.sent ]; then
+ echo "The batch report could not be renamed"
+ ls $RSYSLOG_DYNNAME*
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imbatchreport_rename_toolarge.sh b/tests/imbatchreport_rename_toolarge.sh
new file mode 100755
index 0000000..a43d72c
--- /dev/null
+++ b/tests/imbatchreport_rename_toolarge.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# 804/805 fail/sent with space dedup
+global(maxmessagesize="800")
+module(load="../contrib/imbatchreport/.libs/imbatchreport" pollinginterval="1")
+global(localhostname="server")
+input(type="imbatchreport" ruleset="ruleset" tag="batch"
+ severity="info" facility="local0"
+ reports="./'$RSYSLOG_DYNNAME'*.done" deduplicatespace="on"
+ programkey="KSH" timestampkey="START"
+ rename=".done$ .sent .rejected"
+ )
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="RSYSLOG_SyslogProtocol23Format")
+}
+'
+{
+ echo '164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)'
+ echo '164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree'
+ echo '164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)'
+ echo '164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree'
+ echo '164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)'
+ echo '164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1'
+} > $RSYSLOG_DYNNAME.rtl.done
+case $(uname) in
+ FreeBSD)
+ datelog=$(date -ur $(stat -f %m $RSYSLOG_DYNNAME.rtl.done) "+%Y-%m-%dT%H:%M:%S")
+ ;;
+ *)
+ datelog=$(date "+%Y-%m-%dT%H:%M:%S" -ud @$(stat -c "%Y" $RSYSLOG_DYNNAME.rtl.done))
+ ;;
+esac
+echo "Batch report to consume ${RSYSLOG_DYNNAME}.rtl.done for ${datelog}"
+startup
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='<134>1 '${datelog}'.000000+00:00 server batch - - - File too large : ./'${RSYSLOG_DYNNAME}'.rtl.done'
+cmp_exact
+if [ -e $RSYSLOG_DYNNAME.rtl.done ] || [ -e $RSYSLOG_DYNNAME.rtl.sent ] || [ ! -e $RSYSLOG_DYNNAME.rtl.rejected ]; then
+ echo "The batch report could not be renamed to rejected"
+ ls $RSYSLOG_DYNNAME*
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imdocker-basic-vg.sh b/tests/imdocker-basic-vg.sh
new file mode 100755
index 0000000..e5ca251
--- /dev/null
+++ b/tests/imdocker-basic-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imdocker-basic.sh
diff --git a/tests/imdocker-basic.sh b/tests/imdocker-basic.sh
new file mode 100755
index 0000000..f1a569e
--- /dev/null
+++ b/tests/imdocker-basic.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# imdocker unit tests are enabled with --enable-imdocker-tests
+. ${srcdir:=.}/diag.sh init
+NUMMESSAGES=1000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+export COOKIE=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 10 | head -n 1)
+
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+module(load="../contrib/imdocker/.libs/imdocker"
+ ListContainersOptions="all=true"
+ GetContainerLogOptions="timestamps=0&follow=1&stdout=1&stderr=0")
+if $!metadata!Names == "'$COOKIE'" then {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+
+# launch a docker runtime to generate some logs.
+docker run \
+ --name $COOKIE \
+ -e NUMMESSAGES=$NUMMESSAGES \
+ alpine \
+ /bin/sh -c 'for i in $(seq 0 $((NUMMESSAGES-1))); do echo "$i"; done' > /dev/null
+
+#export RS_REDIR=-d
+startup
+
+shutdown_when_empty
+wait_shutdown
+
+echo "cookie: $COOKIE, file name: $RSYSLOG_OUT_LOG"
+seq_check
+
+docker container rm $COOKIE
+exit_test
diff --git a/tests/imdocker-long-logline-vg.sh b/tests/imdocker-long-logline-vg.sh
new file mode 100755
index 0000000..e93a7f3
--- /dev/null
+++ b/tests/imdocker-long-logline-vg.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imdocker-long-logline.sh
diff --git a/tests/imdocker-long-logline.sh b/tests/imdocker-long-logline.sh
new file mode 100755
index 0000000..469da02
--- /dev/null
+++ b/tests/imdocker-long-logline.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# imdocker unit tests are enabled with --enable-imdocker-tests
+. ${srcdir:=.}/diag.sh init
+export COOKIE=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 10 | head -n 1)
+SIZE=17000
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+module(load="../contrib/imdocker/.libs/imdocker"
+ ListContainersOptions="all=true"
+ GetContainerLogOptions="timestamps=0&follow=1&stdout=1&stderr=0")
+
+if $!metadata!Names == "'$COOKIE'" then {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+}
+
+$MaxMessageSize 64k
+'
+# launch container with a long log line
+docker run \
+ --name $COOKIE \
+ -e size=$SIZE \
+ alpine /bin/sh -c 'echo "$(yes a | head -n $size | tr -d "\n")";' > /dev/null
+
+startup
+wait_file_lines "$RSYSLOG_OUT_LOG" 1
+shutdown_when_empty
+wait_shutdown
+
+# check the log line length
+echo "file name: $RSYSLOG_OUT_LOG"
+count=$(grep "aaaaaaa" $RSYSLOG_OUT_LOG | tr -d "\n" | wc -c)
+
+if [ "x$count" == "x$SIZE" ]; then
+ echo "correct log line length: $count"
+else
+ echo "Incorrect log line length - found $count, expected: $SIZE"
+ error_exit 1
+fi
+
+docker container rm $COOKIE
+exit_test
diff --git a/tests/imdocker-multi-line-vg.sh b/tests/imdocker-multi-line-vg.sh
new file mode 100755
index 0000000..5ca4750
--- /dev/null
+++ b/tests/imdocker-multi-line-vg.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imdocker-multi-line.sh
diff --git a/tests/imdocker-multi-line.sh b/tests/imdocker-multi-line.sh
new file mode 100755
index 0000000..f245fc2
--- /dev/null
+++ b/tests/imdocker-multi-line.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+
+# imdocker unit tests are enabled with --enable-imdocker-tests
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=999
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+export COOKIE=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 10 | head -n 1)
+
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!metadata!Names% %msg%\n")
+
+module(load="../contrib/imdocker/.libs/imdocker" PollingInterval="1"
+ ListContainersOptions="all=true"
+ GetContainerLogOptions="timestamps=0&follow=1&stdout=1&stderr=0")
+
+if $!metadata!Names == "'$COOKIE'" then {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+
+# launch a docker runtime to generate some logs.
+# These logs started after start-up should get from beginning
+docker run \
+ --name $COOKIE \
+ -e num_items=$((NUMMESSAGES+1)) \
+ -l imdocker.startregex=^multi-line: \
+ alpine \
+ /bin/sh -c \
+ 'for i in `seq 1 $num_items`; do printf "multi-line: $i\n line2....\n line3....\n"; done' > /dev/null
+
+startup
+shutdown_when_empty
+wait_shutdown
+docker container rm $COOKIE
+
+content_check_with_count "$COOKIE multi-line:" $NUMMESSAGES 10
+## check if all the data we expect to get in the file is there
+for i in $(seq 1 $NUMMESSAGES); do
+ grep "$COOKIE multi-line: $i#012 line2....#012 line3...." $RSYSLOG_OUT_LOG > /dev/null 2>&1
+ if [ ! $? -eq 0 ]; then
+ echo "ERROR: expecting the string $COOKIE multi-line: item '$i', it's not there"
+ error_exit 1
+ fi
+done
+exit_test
diff --git a/tests/imdocker-new-logs-from-start-vg.sh b/tests/imdocker-new-logs-from-start-vg.sh
new file mode 100755
index 0000000..1332fcd
--- /dev/null
+++ b/tests/imdocker-new-logs-from-start-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imdocker-new-logs-from-start.sh
diff --git a/tests/imdocker-new-logs-from-start.sh b/tests/imdocker-new-logs-from-start.sh
new file mode 100755
index 0000000..aaaf07d
--- /dev/null
+++ b/tests/imdocker-new-logs-from-start.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# imdocker unit tests are enabled with --enable-imdocker-tests
+. ${srcdir:=.}/diag.sh init
+export COOKIE=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 10 | head -n 1)
+generate_conf
+add_conf '
+#template(name="template_msg_only" type="string" string="%msg%\n")
+template(name="outfmt" type="string" string="%$!metadata!Names% %msg%\n")
+module(load="../contrib/imdocker/.libs/imdocker" PollingInterval="1"
+ ListContainersOptions="all=true"
+ GetContainerLogOptions="tail=1&timestamps=0&follow=1&stdout=1&stderr=0&tail=1"
+ RetrieveNewLogsFromStart="on"
+ )
+action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+
+if $!metadata!Names == "'$COOKIE'" then {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+
+#NUM_ITEMS=1000
+# launch a docker runtime to generate some logs.
+# these log items should be tailed.
+docker run \
+ --rm \
+ -e seq_start=101 \
+ -e seq_end=200 \
+ alpine \
+ /bin/sh -c 'for i in `seq $seq_start $seq_end`; do echo "tailed item $i"; sleep .01; done' > /dev/null &
+
+sleep 1
+
+#export RS_REDIR=-d
+startup
+NUMMESSAGES=1000
+# launch a docker runtime to generate some logs.
+# These logs started after start-up should get from beginning
+docker run \
+ --name $COOKIE \
+ -e NUMMESSAGES=$NUMMESSAGES \
+ alpine \
+ /bin/sh -c 'for i in `seq 1 $NUMMESSAGES`; do echo "log item $i"; done' > /dev/null
+
+shutdown_when_empty
+wait_shutdown
+
+echo "file name: $RSYSLOG_OUT_LOG"
+echo "\"tailed item\" occurred: $(grep -c 'tailed item ' $RSYSLOG_OUT_LOG)/100 (expect less)."
+
+docker container rm $COOKIE
+exit_test
+
diff --git a/tests/imdtls-basic-timeout b/tests/imdtls-basic-timeout
new file mode 100755
index 0000000..9b4c46a
--- /dev/null
+++ b/tests/imdtls-basic-timeout
@@ -0,0 +1,45 @@
+#!/bin/bash
+# added 2023-10-05 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=2000
+export SENDESSAGES=500
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+export TIMEOUT="5"
+
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imdtls/.libs/imdtls" )
+# tls.authmode="anon" )
+input( type="imdtls"
+ port="'$PORT_RCVR'"
+ timeout="'$TIMEOUT'"
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omfile"
+ template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+# Begin actual testcase
+
+startup
+# valgrind --tool=helgrind $RS_TEST_VALGRIND_EXTRA_OPTS $RS_TESTBENCH_VALGRIND_EXTRA_OPTS --log-fd=1 --error-exitcode=10
+./tcpflood -b1 -W1000 -p$PORT_RCVR -m$SENDESSAGES -Tdtls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem -L0
+# ./msleep 500
+./tcpflood -b1 -W1000 -i500 -p$PORT_RCVR -m$SENDESSAGES -Tdtls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem -L0
+./tcpflood -b1 -W1000 -i1000 -p$PORT_RCVR -m$SENDESSAGES -Tdtls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem -L0
+./tcpflood -b1 -W1000 -i1500 -p$PORT_RCVR -m$SENDESSAGES -Tdtls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem -L0
+
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imdtls-basic-tlscommands.sh b/tests/imdtls-basic-tlscommands.sh
new file mode 100755
index 0000000..0a65351
--- /dev/null
+++ b/tests/imdtls-basic-tlscommands.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# added 2018-04-27 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+
+module( load="../plugins/imdtls/.libs/imdtls" )
+input( type="imdtls"
+ tls.tlscfgcmd="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.1,-TLSv1.3
+ Options=Bugs"
+ port="'$PORT_RCVR'")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+
+# now inject the messages which will fail due protocol configuration
+tcpflood --check-only -k "Protocol=-ALL,TLSv1.3" -p$PORT_RCVR -m$NUMMESSAGES -Tdtls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+
+shutdown_when_empty
+wait_shutdown
+
+if content_check --check-only "TLS library does not support SSL_CONF_cmd"
+then
+ echo "SKIP: TLS library does not support SSL_CONF_cmd"
+ skip_test
+else
+ if content_check --check-only "DTLSv1_listen"
+ then
+ # Found DTLSv1_listen error, no further check needed
+ exit_test
+ else
+ # Check for OpenSSL Error Stack
+ content_check "OpenSSL Error Stack:"
+ fi
+fi
+
+exit_test
diff --git a/tests/imdtls-basic-vg.sh b/tests/imdtls-basic-vg.sh
new file mode 100755
index 0000000..fba111f
--- /dev/null
+++ b/tests/imdtls-basic-vg.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+if [ "$(valgrind --version)" == "valgrind-3.11.0" ]; then
+ printf 'This test does NOT work with valgrind-3.11.0 - valgrind always reports\n'
+ printf 'a valgrind-internal bug. So we need to skip it.\n'
+ exit 77
+fi
+export USE_VALGRIND="YES"
+export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes"
+source ${srcdir:-.}/imdtls-basic.sh
diff --git a/tests/imdtls-basic.sh b/tests/imdtls-basic.sh
new file mode 100755
index 0000000..889caad
--- /dev/null
+++ b/tests/imdtls-basic.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# added 2023-10-05 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imdtls/.libs/imdtls" )
+# tls.authmode="anon" )
+input( type="imdtls"
+ port="'$PORT_RCVR'")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omfile"
+ template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+# Begin actual testcase
+
+startup
+# valgrind --tool=helgrind $RS_TEST_VALGRIND_EXTRA_OPTS $RS_TESTBENCH_VALGRIND_EXTRA_OPTS --log-fd=1 --error-exitcode=10
+./tcpflood -b1 -W1000 -p$PORT_RCVR -m$NUMMESSAGES -Tdtls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem -L0
+
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imdtls-error-cert.sh b/tests/imdtls-error-cert.sh
new file mode 100755
index 0000000..12a1138
--- /dev/null
+++ b/tests/imdtls-error-cert.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2018-11-07 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert-fail.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/cert.pem'"
+)
+
+module( load="../plugins/imdtls/.libs/imdtls" )
+input( type="imdtls"
+ port="'$PORT_RCVR'")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+# note: we do not need to generate any messages, config error occurs on startup
+startup
+
+sleep 5 # TODO: FIXME - just checking if we terminate too early
+shutdown_when_empty
+wait_shutdown
+content_check "Error: Certificate file could not be accessed"
+content_check "OpenSSL Error Stack:"
+exit_test
diff --git a/tests/imdtls-sessionbreak-vg.sh b/tests/imdtls-sessionbreak-vg.sh
new file mode 100755
index 0000000..aed1b5a
--- /dev/null
+++ b/tests/imdtls-sessionbreak-vg.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+if [ "$(valgrind --version)" == "valgrind-3.11.0" ]; then
+ printf 'This test does NOT work with valgrind-3.11.0 - valgrind always reports\n'
+ printf 'a valgrind-internal bug. So we need to skip it.\n'
+ exit 77
+fi
+export USE_VALGRIND="YES"
+export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes"
+source ${srcdir:-.}/imdtls-sessionbreak.sh
diff --git a/tests/imdtls-sessionbreak.sh b/tests/imdtls-sessionbreak.sh
new file mode 100755
index 0000000..89104ca
--- /dev/null
+++ b/tests/imdtls-sessionbreak.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+# added 2020-04-10 by alorbach, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+export USE_VALGRIND="yes"
+# TODO remote leak check skip and fix memory leaks caused by session break
+export RS_TESTBENCH_LEAK_CHECK=no
+export PORT_RCVR="$(get_free_port)"
+
+mkdir $RSYSLOG_DYNNAME.workdir
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem"
+ workDirectory="'$RSYSLOG_DYNNAME.workdir'"
+ maxMessageSize="256k")
+main_queue(queue.type="Direct")
+
+$LocalHostName test
+$AbortOnUncleanConfig on
+$PreserveFQDN on
+
+module( load="../plugins/imdtls/.libs/imdtls"
+ tls.AuthMode="x509/certvalid")
+
+input( type="imdtls"
+ port="'$PORT_RCVR'"
+ ruleset="spool"
+)
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+ruleset(name="spool" queue.type="direct") {
+ if $msg contains "msgnum:" then {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+ }
+}
+'
+startup
+# How many tcpfloods we run at the same tiem
+for ((i=1;i<=10;i++)); do
+ # How many times tcpflood runs in each threads
+ ./tcpflood -Tdtls -p$PORT_RCVR -m$NUMMESSAGES -W1000 -d102400 -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem -s &
+ tcpflood_pid=$!
+
+ echo "started tcpflood instance $i (PID $tcpflood_pid)"
+
+ # Give it time to actually connect
+ ./msleep 1000;
+
+ kill -9 $tcpflood_pid # >/dev/null 2>&1;
+ echo "killed tcpflood instance $i (PID $tcpflood_pid)"
+done;
+
+wait_queueempty
+
+netstatresult=$(netstat --all --program 2>&1 | grep "ESTABLISHED" | grep $(cat $RSYSLOG_PIDBASE.pid) | grep $TCPFLOOD_PORT)
+openfd=$(ls -l "/proc/$(cat $RSYSLOG_PIDBASE$1.pid)/fd" | wc -l)
+
+shutdown_when_empty
+wait_shutdown
+
+if [[ "$netstatresult" == "" ]]
+then
+ echo "OK!"
+else
+ echo "STILL OPENED Connections: "
+ echo $netstatresult
+ echo "Open files at the end: "
+ echo $openfd
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imfile-basic-2GB-file.sh b/tests/imfile-basic-2GB-file.sh
new file mode 100755
index 0000000..d6b40d1
--- /dev/null
+++ b/tests/imfile-basic-2GB-file.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# written 2018-11-09 by Rainer Gerhards
+# this test checks that 2GiB (31 bit) file size region is handled correctly
+# it first generates a file that is 2GiB-64 bytes, processes it, and then
+# adds a couple of messages to get it over 2GiB.
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export TB_TEST_MAX_RUNTIME=3600 # test is very slow as it works on large files
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+touch $RSYSLOG_DYNNAME.input
+startup
+
+# initial file: 2GiB - 1 message (54 byte)
+./inputfilegen -s 2147483584 -d47 -M $RSYSLOG_DYNNAME.msgcnt > $RSYSLOG_DYNNAME.input
+ls -lh $RSYSLOG_DYNNAME.input
+export NUMMESSAGES="$(cat $RSYSLOG_DYNNAME.msgcnt)"
+
+wait_file_lines --delay 2500 --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES 3000
+
+# add one message --> exactly 2GB
+./inputfilegen -m1 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input
+ls -lh $RSYSLOG_DYNNAME.input
+(( NUMMESSAGES++ ))
+wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES
+
+# add one more message --> now we go over 2GB
+./inputfilegen -m1 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input
+ls -lh $RSYSLOG_DYNNAME.input
+(( NUMMESSAGES++ ))
+wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES
+
+# add even more messages
+./inputfilegen -m10000 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input
+ls -lh $RSYSLOG_DYNNAME.input
+NUMMESSAGES=$(( NUMMESSAGES + 10000 ))
+wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES
+
+shutdown_when_empty
+wait_shutdown
+seq_check 0 $(( NUMMESSAGES - 1))
+exit_test
diff --git a/tests/imfile-basic-legacy.sh b/tests/imfile-basic-legacy.sh
new file mode 100755
index 0000000..f08f5d5
--- /dev/null
+++ b/tests/imfile-basic-legacy.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+NUMMESSAGES=50000
+mkdir WorkDirectory $RSYSLOG_DYNNAME.work
+generate_conf
+add_conf '
+$WorkDirectory '$RSYSLOG_DYNNAME'.work
+$ModLoad ../plugins/imfile/.libs/imfile
+$InputFileName ./'$RSYSLOG_DYNNAME'.input
+$InputFileTag file:
+$InputFileStateFile stat-file1
+$InputFileSeverity error
+$InputFileFacility local7
+$InputFileMaxLinesAtOnce 100000
+$InputRunFileMonitor
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+# generate input file first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+./inputfilegen -m $NUMMESSAGES > $RSYSLOG_DYNNAME.input
+startup
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imfile-basic-vg.sh b/tests/imfile-basic-vg.sh
new file mode 100755
index 0000000..586e7db
--- /dev/null
+++ b/tests/imfile-basic-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imfile-basic.sh
diff --git a/tests/imfile-basic-vgthread.sh b/tests/imfile-basic-vgthread.sh
new file mode 100755
index 0000000..53b78d2
--- /dev/null
+++ b/tests/imfile-basic-vgthread.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test currently does not work on FreeBSD."
+export NUMMESSAGES=50000
+if grep -q 'release 6\.' <<< "$(cat /etc/redhat-release 2>/dev/null)"; then
+ echo "RHEL/CentOS 6 detected, adding valgrind suppressions"
+ export RS_TEST_VALGRIND_EXTRA_OPTS="--suppressions=${srcdir}/imfile-basic-vgthread.supp"
+fi
+
+exit
+generate_conf
+add_conf '
+$ModLoad ../plugins/imfile/.libs/imfile
+$InputFileName ./'$RSYSLOG_DYNNAME'.input
+$InputFileTag file:
+$InputFileStateFile stat-file1
+$InputFileSeverity error
+$InputFileFacility local7
+$InputFileMaxLinesAtOnce 100000
+$InputRunFileMonitor
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" ./'$RSYSLOG_OUT_LOG';outfmt
+'
+
+# generate input file first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+./inputfilegen -m $NUMMESSAGES > $RSYSLOG_DYNNAME.input
+ls -l $RSYSLOG_DYNNAME.input
+
+startup_vgthread
+wait_file_lines
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+seq_check
+exit_test
diff --git a/tests/imfile-basic.sh b/tests/imfile-basic.sh
new file mode 100755
index 0000000..a87fbd4
--- /dev/null
+++ b/tests/imfile-basic.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+generate_conf
+# NOTE: do NOT set a working directory!
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" tag="file:")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+else
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.othermsgs")
+'
+# make sure file exists when rsyslog starts up
+touch $RSYSLOG_DYNNAME.input
+startup
+./inputfilegen -m $NUMMESSAGES >> $RSYSLOG_DYNNAME.input
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check
+content_check "imfile: no working or state file directory set" $RSYSLOG_DYNNAME.othermsgs
+exit_test
diff --git a/tests/imfile-discard-truncated-line.sh b/tests/imfile-discard-truncated-line.sh
new file mode 100755
index 0000000..4cc95e1
--- /dev/null
+++ b/tests/imfile-discard-truncated-line.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# This test mimics the test imfile-readmode2.sh, but works via
+# endmsg.regex. It's kind of a base test for the regex functionality.
+echo ======================================================================
+# Check if inotify header exist
+echo [imfile-discard-truncated-line.sh]
+. $srcdir/diag.sh check-inotify
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 128
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ discardTruncatedMsg="on"
+ msgDiscardingError="off"
+ Tag="file:"
+ startmsg.regex="^[^ ]"
+ ruleset="ruleset")
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt")
+'
+startup
+
+# write the beginning of the file
+echo 'msgnum:0
+msgnum:1
+msgnum:2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ msgnum:3 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ msgnum:4 cccccccccccccccccccccccccccccccccccccccccccc
+ msgnum:5 dddddddddddddddddddddddddddddddddddddddddddd
+msgnum:6 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+ msgnum:7 ffffffffffffffffffffffffffffffffffffffffffff
+ msgnum:8 gggggggggggggggggggggggggggggggggggggggggggg
+msgnum:9' > $RSYSLOG_DYNNAME.input
+# the next line terminates our test. It is NOT written to the output file,
+# as imfile waits whether or not there is a follow-up line that it needs
+# to combine.
+echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input
+# sleep a little to give rsyslog a chance to begin processing
+./msleep 500
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+printf 'HEADER msgnum:0
+HEADER msgnum:1
+HEADER msgnum:2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\\n msgnum:3 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\\\\n msgnum:4 ccccccc
+HEADER msgnum:6 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\\\\n msgnum:7 ffffffffffffffffffffffffffffffffffffffffffff\\\\n msgnum:8 ggggggg
+HEADER msgnum:9\n' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid multiline message generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi;
+
+grep "imfile error:.*rest of message will not be processed" ${RSYSLOG2_OUT_LOG} > /dev/null
+if [ $? -eq 0 ]; then
+ echo
+ echo "FAIL: expected error message from missing input file not found. ${RSYSLOG2_OUT_LOG} is:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imfile-endmsg.regex-vg.sh b/tests/imfile-endmsg.regex-vg.sh
new file mode 100755
index 0000000..abd3442
--- /dev/null
+++ b/tests/imfile-endmsg.regex-vg.sh
@@ -0,0 +1,111 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# This test tests imfile endmsg.regex.
+USE_VALGRIND=true
+echo ======================================================================
+echo [imfile-endmsg.regex.sh]
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.crio.input"
+ Tag="file:" addMetadata="on" escapelf="on"
+ endmsg.regex="^[^ ]+ (stdout|stderr) F ")
+
+template(name="outfmt" type="list") {
+ property(name="$!all-json-plain")
+ constant(value=" ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+if [ "${USE_VALGRIND:-false}" == "true" ] ; then
+ startup_vg
+else
+ startup
+fi
+if [ -n "${USE_GDB:-}" ] ; then
+ echo attach gdb here
+ sleep 54321 || :
+fi
+
+# write the beginning of the file
+echo 'date stdout P msgnum:0' > $RSYSLOG_DYNNAME.crio.input
+echo 'date stdout F msgnum:1' >> $RSYSLOG_DYNNAME.crio.input
+echo 'date stdout F msgnum:2' >> $RSYSLOG_DYNNAME.crio.input
+
+# sleep a little to give rsyslog a chance to begin processing
+if [ -n "${USE_GDB:-}" ] ; then
+ sleep 54321 || :
+else
+ sleep 1
+fi
+
+echo 'date stdout P msgnum:3' >> $RSYSLOG_DYNNAME.crio.input
+echo 'date stdout P msgnum:4' >> $RSYSLOG_DYNNAME.crio.input
+echo 'date stdout P msgnum:5' >> $RSYSLOG_DYNNAME.crio.input
+
+# give it time to finish
+if [ -n "${USE_GDB:-}" ] ; then
+ sleep 54321 || :
+else
+ sleep 1
+fi
+
+echo 'date stdout F msgnum:6' >> $RSYSLOG_DYNNAME.crio.input
+echo 'date stdout P msgnum:7' >> $RSYSLOG_DYNNAME.crio.input
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+if [ "${USE_VALGRIND:-false}" == "true" ] ; then
+ wait_shutdown_vg
+ check_exit_vg
+else
+ wait_shutdown # we need to wait until rsyslogd is finished!
+fi
+
+# give it time to write the output file
+sleep 1
+
+## check if we have the correct number of messages
+
+NUMLINES=$(wc -l $RSYSLOG_OUT_LOG | awk '{print $1}' 2>/dev/null)
+
+rc=0
+if [ ! $NUMLINES -eq 3 ]; then
+ echo "ERROR: expecting 3 lines, got $NUMLINES"
+ rc=1
+fi
+
+## check if all the data we expect to get in the file is there
+
+for string in "metadata.*filename.*crio[.]input.*msgnum:0.*msgnum:1" \
+ "metadata.*filename.*crio[.]input.*msgnum:2" \
+ "metadata.*filename.*crio[.]input.*msgnum:3.*msgnum:4.*msgnum:5.*msgnum:6" ; do
+ if grep "$string" $RSYSLOG_OUT_LOG > /dev/null 2>&1 ; then
+ : # ok
+ else
+ echo "Error: the expected string '$string' not found"
+ rc=1
+ fi
+done
+
+if [ $rc -ne 0 ]; then
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi
+
+## if we got here, all is good :)
+
+exit_test
diff --git a/tests/imfile-endmsg.regex-with-example-vg.sh b/tests/imfile-endmsg.regex-with-example-vg.sh
new file mode 100755
index 0000000..76d7431
--- /dev/null
+++ b/tests/imfile-endmsg.regex-with-example-vg.sh
@@ -0,0 +1,147 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# This test tests imfile endmsg.regex.
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+export USE_VALGRIND="YES"
+
+mkdir $RSYSLOG_DYNNAME.statefiles
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+
+input(type="imfile"
+ statefile.directory="'${RSYSLOG_DYNNAME}'.statefiles"
+ File="./'$RSYSLOG_DYNNAME'.*.input"
+ Tag="file:" addMetadata="on" escapelf="off"
+ endmsg.regex="(^[^ ]+ (stdout|stderr) F )|(\\n\"}$)")
+
+if $msg startswith "{" then {
+ action(type="mmnormalize" rulebase="'$srcdir/imfile-endmsg.regex.json.rulebase'")
+ foreach ($.ii in $!multilinejson) do {
+ if strlen($!@timestamp) == 0 then {
+ set $!@timestamp = $.ii!time;
+ }
+ if strlen($!stream) == 0 then {
+ set $!stream = $.ii!stream;
+ }
+ if strlen($!log) == 0 then {
+ set $!log = $.ii!log;
+ } else {
+ reset $!log = $!log & $.ii!log;
+ }
+ }
+ unset $!multilinejson;
+} else {
+ action(type="mmnormalize" rulebase="'$srcdir/imfile-endmsg.regex.crio.rulebase'")
+ foreach ($.ii in $!multilinecrio) do {
+ if strlen($!@timestamp) == 0 then {
+ set $!@timestamp = $.ii!time;
+ }
+ if strlen($!stream) == 0 then {
+ set $!stream = $.ii!stream;
+ }
+ if strlen($!log) == 0 then {
+ set $!log = $.ii!log;
+ } else {
+ reset $!log = $!log & $.ii!log;
+ }
+ }
+ unset $!multilinecrio;
+}
+
+template(name="outfmt" type="list") {
+ property(name="$!all-json-plain")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup
+if [ -n "${USE_GDB:-}" ] ; then
+ echo attach gdb here
+ sleep 54321 || :
+fi
+
+# write the beginning of the file
+echo 'date stdout P msgnum:0' > $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:0"}' > $RSYSLOG_DYNNAME.json.input
+echo 'date stdout F msgnum:1' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:1\n"}' >> $RSYSLOG_DYNNAME.json.input
+echo 'date stdout F msgnum:2' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:2\n"}' >> $RSYSLOG_DYNNAME.json.input
+
+if [ -n "${USE_GDB:-}" ] ; then
+ sleep 54321 || :
+fi
+
+wait_file_lines $RSYSLOG_OUT_LOG 4
+
+echo 'date stdout P msgnum:3' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:3"}' >> $RSYSLOG_DYNNAME.json.input
+echo 'date stdout P msgnum:4' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:4"}' >> $RSYSLOG_DYNNAME.json.input
+echo 'date stdout P msgnum:5' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:5"}' >> $RSYSLOG_DYNNAME.json.input
+
+# give it time to finish
+if [ -n "${USE_GDB:-}" ] ; then
+ sleep 54321 || :
+else
+ sleep 1 # of course, this is racy
+fi
+# so we do at least wait for the queue to be empty - this should work in hopefully most cases
+wait_queueempty
+
+echo 'date stdout F msgnum:6' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:6\n"}' >> $RSYSLOG_DYNNAME.json.input
+echo 'date stdout P msgnum:7' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:7"}' >> $RSYSLOG_DYNNAME.json.input
+
+wait_file_lines $RSYSLOG_OUT_LOG 6
+
+shutdown_when_empty
+wait_shutdown
+
+
+## check if we have the correct number of messages
+
+NUMLINES=$(wc -l $RSYSLOG_OUT_LOG | awk '{print $1}' 2>/dev/null)
+
+rc=0
+if [ ! $NUMLINES -eq 6 ]; then
+ echo "ERROR: expecting 6 lines, got $NUMLINES"
+ cat -n $RSYSLOG_OUT_LOG
+ rc=1
+fi
+
+## check if all the data we expect to get in the file is there
+
+for string in "metadata.*filename.*json[.]input.*msgnum:0msgnum:1" \
+ "metadata.*filename.*crio[.]input.*msgnum:0msgnum:1" \
+ "metadata.*filename.*json[.]input.*msgnum:2" \
+ "metadata.*filename.*crio[.]input.*msgnum:2" \
+ "metadata.*filename.*json[.]input.*msgnum:3msgnum:4msgnum:5msgnum:6" \
+ "metadata.*filename.*crio[.]input.*msgnum:3msgnum:4msgnum:5msgnum:6" ; do
+ if grep "$string" $RSYSLOG_OUT_LOG > /dev/null 2>&1 ; then
+ : # ok
+ else
+ echo "Error: the expected string '$string' not found"
+ rc=1
+ fi
+done
+
+if [ $rc -ne 0 ]; then
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+## if we got here, all is good :)
+
+exit_test
diff --git a/tests/imfile-endmsg.regex-with-example.sh b/tests/imfile-endmsg.regex-with-example.sh
new file mode 100755
index 0000000..4bcd126
--- /dev/null
+++ b/tests/imfile-endmsg.regex-with-example.sh
@@ -0,0 +1,157 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# This test tests imfile endmsg.regex.
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+export IMFILECHECKTIMEOUT="60"
+export IMFILELASTINPUTLINES="6"
+
+mkdir $RSYSLOG_DYNNAME.statefiles
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+
+input(type="imfile"
+ statefile.directory="'${RSYSLOG_DYNNAME}'.statefiles"
+ File="./'$RSYSLOG_DYNNAME'.*.input"
+ Tag="file:" addMetadata="on" escapelf="off"
+ endmsg.regex="(^[^ ]+ (stdout|stderr) F )|(\\n\"}$)")
+
+if $msg startswith "{" then {
+ action(type="mmnormalize" rulebase="'$srcdir/imfile-endmsg.regex.json.rulebase'")
+ foreach ($.ii in $!multilinejson) do {
+ if strlen($!@timestamp) == 0 then {
+ set $!@timestamp = $.ii!time;
+ }
+ if strlen($!stream) == 0 then {
+ set $!stream = $.ii!stream;
+ }
+ if strlen($!log) == 0 then {
+ set $!log = $.ii!log;
+ } else {
+ reset $!log = $!log & $.ii!log;
+ }
+ }
+ unset $!multilinejson;
+} else {
+ action(type="mmnormalize" rulebase="'$srcdir/imfile-endmsg.regex.crio.rulebase'")
+ foreach ($.ii in $!multilinecrio) do {
+ if strlen($!@timestamp) == 0 then {
+ set $!@timestamp = $.ii!time;
+ }
+ if strlen($!stream) == 0 then {
+ set $!stream = $.ii!stream;
+ }
+ if strlen($!log) == 0 then {
+ set $!log = $.ii!log;
+ } else {
+ reset $!log = $!log & $.ii!log;
+ }
+ }
+ unset $!multilinecrio;
+}
+
+template(name="outfmt" type="list") {
+ property(name="$!all-json-plain")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+if [ "${USE_VALGRIND:-false}" == "true" ] ; then
+ startup_vg
+else
+ startup
+fi
+if [ -n "${USE_GDB:-}" ] ; then
+ echo attach gdb here
+ sleep 54321 || :
+fi
+
+# write the beginning of the file
+echo 'date stdout P msgnum:0' > $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:0"}' > $RSYSLOG_DYNNAME.json.input
+echo 'date stdout F msgnum:1' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:1\n"}' >> $RSYSLOG_DYNNAME.json.input
+echo 'date stdout F msgnum:2' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:2\n"}' >> $RSYSLOG_DYNNAME.json.input
+
+# sleep a little to give rsyslog a chance to begin processing
+if [ -n "${USE_GDB:-}" ] ; then
+ sleep 54321 || :
+else
+ sleep 1
+fi
+
+echo 'date stdout P msgnum:3' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:3"}' >> $RSYSLOG_DYNNAME.json.input
+echo 'date stdout P msgnum:4' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:4"}' >> $RSYSLOG_DYNNAME.json.input
+echo 'date stdout P msgnum:5' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:5"}' >> $RSYSLOG_DYNNAME.json.input
+
+# give it time to finish
+if [ -n "${USE_GDB:-}" ] ; then
+ sleep 54321 || :
+else
+ sleep 1
+fi
+
+echo 'date stdout F msgnum:6' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:6\n"}' >> $RSYSLOG_DYNNAME.json.input
+echo 'date stdout P msgnum:7' >> $RSYSLOG_DYNNAME.crio.input
+echo '{"time":"date", "stream":"stdout", "log":"msgnum:7"}' >> $RSYSLOG_DYNNAME.json.input
+
+content_check_with_count "$RSYSLOG_DYNNAME" $IMFILELASTINPUTLINES $IMFILECHECKTIMEOUT
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+if [ "${USE_VALGRIND:-false}" == "true" ] ; then
+ wait_shutdown_vg
+ check_exit_vg
+else
+ wait_shutdown # we need to wait until rsyslogd is finished!
+fi
+
+# give it time to write the output file
+sleep 1
+
+## check if we have the correct number of messages
+
+NUMLINES=$(wc -l $RSYSLOG_OUT_LOG | awk '{print $1}' 2>/dev/null)
+
+rc=0
+if [ ! $NUMLINES -eq $IMFILELASTINPUTLINES ]; then
+ echo "ERROR: expecting $IMFILELASTINPUTLINES lines, got $NUMLINES"
+ rc=1
+fi
+
+## check if all the data we expect to get in the file is there
+
+for string in "metadata.*filename.*json[.]input.*msgnum:0msgnum:1" \
+ "metadata.*filename.*crio[.]input.*msgnum:0msgnum:1" \
+ "metadata.*filename.*json[.]input.*msgnum:2" \
+ "metadata.*filename.*crio[.]input.*msgnum:2" \
+ "metadata.*filename.*json[.]input.*msgnum:3msgnum:4msgnum:5msgnum:6" \
+ "metadata.*filename.*crio[.]input.*msgnum:3msgnum:4msgnum:5msgnum:6" ; do
+ if grep "$string" $RSYSLOG_OUT_LOG > /dev/null 2>&1 ; then
+ : # ok
+ else
+ echo "Error: the expected string '$string' not found"
+ rc=1
+ fi
+done
+
+if [ $rc -ne 0 ]; then
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi
+
+## if we got here, all is good :)
+
+exit_test
diff --git a/tests/imfile-endmsg.regex.crio.rulebase b/tests/imfile-endmsg.regex.crio.rulebase
new file mode 100644
index 0000000..002ef44
--- /dev/null
+++ b/tests/imfile-endmsg.regex.crio.rulebase
@@ -0,0 +1,15 @@
+version=2
+rule=:%{"name":"multilinecrio", "type":"repeat",
+ "parser":[
+ {"type":"word", "name":"time"},
+ {"type":"literal", "text":" "},
+ {"type":"word", "name":"stream"},
+ {"type":"literal", "text":" "},
+ {"type":"word", "name":"partial"},
+ {"type":"literal", "text":" "},
+ {"type":"char-sep", "name":"log", "extradata":"\n"}
+ ],
+ "while":[
+ {"type":"literal", "text":"\n"},
+ ]
+ }%
diff --git a/tests/imfile-endmsg.regex.json.rulebase b/tests/imfile-endmsg.regex.json.rulebase
new file mode 100644
index 0000000..6bdfac0
--- /dev/null
+++ b/tests/imfile-endmsg.regex.json.rulebase
@@ -0,0 +1,9 @@
+version=2
+rule=:%{"name":"multilinejson", "type":"repeat", "option.permitMismatchInParser": true,
+ "parser":[
+ {"type":"json", "name":"."}
+ ],
+ "while":[
+ {"type":"char-sep", "extradata":"{"}
+ ]
+ }%
diff --git a/tests/imfile-endmsg.regex.sh b/tests/imfile-endmsg.regex.sh
new file mode 100755
index 0000000..e2c5911
--- /dev/null
+++ b/tests/imfile-endmsg.regex.sh
@@ -0,0 +1,110 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# This test tests imfile endmsg.regex.
+echo ======================================================================
+echo [imfile-endmsg.regex.sh]
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.crio.input"
+ Tag="file:" addMetadata="on" escapelf="on"
+ endmsg.regex="^[^ ]+ (stdout|stderr) F ")
+
+template(name="outfmt" type="list") {
+ property(name="$!all-json-plain")
+ constant(value=" ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+if [ "${USE_VALGRIND:-false}" == "true" ] ; then
+ startup_vg
+else
+ startup
+fi
+if [ -n "${USE_GDB:-}" ] ; then
+ echo attach gdb here
+ sleep 54321 || :
+fi
+
+# write the beginning of the file
+echo 'date stdout P msgnum:0' > $RSYSLOG_DYNNAME.crio.input
+echo 'date stdout F msgnum:1' >> $RSYSLOG_DYNNAME.crio.input
+echo 'date stdout F msgnum:2' >> $RSYSLOG_DYNNAME.crio.input
+
+# sleep a little to give rsyslog a chance to begin processing
+if [ -n "${USE_GDB:-}" ] ; then
+ sleep 54321 || :
+else
+ sleep 1
+fi
+
+echo 'date stdout P msgnum:3' >> $RSYSLOG_DYNNAME.crio.input
+echo 'date stdout P msgnum:4' >> $RSYSLOG_DYNNAME.crio.input
+echo 'date stdout P msgnum:5' >> $RSYSLOG_DYNNAME.crio.input
+
+# give it time to finish
+if [ -n "${USE_GDB:-}" ] ; then
+ sleep 54321 || :
+else
+ sleep 1
+fi
+
+echo 'date stdout F msgnum:6' >> $RSYSLOG_DYNNAME.crio.input
+echo 'date stdout P msgnum:7' >> $RSYSLOG_DYNNAME.crio.input
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+if [ "${USE_VALGRIND:-false}" == "true" ] ; then
+ wait_shutdown_vg
+ check_exit_vg
+else
+ wait_shutdown # we need to wait until rsyslogd is finished!
+fi
+
+# give it time to write the output file
+sleep 1
+
+## check if we have the correct number of messages
+
+NUMLINES=$(wc -l $RSYSLOG_OUT_LOG | awk '{print $1}' 2>/dev/null)
+
+rc=0
+if [ ! $NUMLINES -eq 3 ]; then
+ echo "ERROR: expecting 3 lines, got $NUMLINES"
+ rc=1
+fi
+
+## check if all the data we expect to get in the file is there
+
+for string in "metadata.*filename.*crio[.]input.*msgnum:0.*msgnum:1" \
+ "metadata.*filename.*crio[.]input.*msgnum:2" \
+ "metadata.*filename.*crio[.]input.*msgnum:3.*msgnum:4.*msgnum:5.*msgnum:6" ; do
+ if grep "$string" $RSYSLOG_OUT_LOG > /dev/null 2>&1 ; then
+ : # ok
+ else
+ echo "Error: the expected string '$string' not found"
+ rc=1
+ fi
+done
+
+if [ $rc -ne 0 ]; then
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi
+
+## if we got here, all is good :)
+
+exit_test
diff --git a/tests/imfile-endregex-save-lf-persist.sh b/tests/imfile-endregex-save-lf-persist.sh
new file mode 100755
index 0000000..460b8e3
--- /dev/null
+++ b/tests/imfile-endregex-save-lf-persist.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+echo ======================================================================
+echo [imfile-endregex-save-lf-persist.sh]
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ PersistStateInterval="1"
+ startmsg.regex="^[^ ]")
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup
+
+# we need to sleep a bit between writes to give imfile a chance
+# to pick up the data (IN MULTIPLE ITERATIONS!)
+echo 'msgnum:0
+ msgnum:1
+ msgnum:2' > $RSYSLOG_DYNNAME.input
+./msleep 300
+echo 'msgnum:3' >> $RSYSLOG_DYNNAME.input
+echo 'msgnum:4
+ msgnum:5' >> $RSYSLOG_DYNNAME.input
+./msleep 200
+# the next line terminates our test. It is NOT written to the output file,
+# as imfile waits whether or not there is a follow-up line that it needs
+# to combine.
+echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input
+./msleep 200
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+printf 'HEADER msgnum:0\\\\n msgnum:1\\\\n msgnum:2
+HEADER msgnum:3
+HEADER msgnum:4\\\\n msgnum:5\n' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid multiline message generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi;
+
+exit_test
diff --git a/tests/imfile-endregex-save-lf.sh b/tests/imfile-endregex-save-lf.sh
new file mode 100755
index 0000000..32725f4
--- /dev/null
+++ b/tests/imfile-endregex-save-lf.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# This test mimics the test imfile-readmode2.sh, but works via
+# endmsg.regex. It's kind of a base test for the regex functionality.
+echo ======================================================================
+echo [imfile-endregex-save-lf.sh]
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ startmsg.regex="^[^ ]")
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup
+
+# write the beginning of the file
+echo 'msgnum:0
+ msgnum:1
+ msgnum:2' > $RSYSLOG_DYNNAME.input
+# the next line terminates our test. It is NOT written to the output file,
+# as imfile waits whether or not there is a follow-up line that it needs
+# to combine.
+echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input
+# sleep a little to give rsyslog a chance to begin processing
+./msleep 500
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+printf 'HEADER msgnum:0\\\\n msgnum:1\\\\n msgnum:2\n' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid multiline message generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi;
+
+exit_test
diff --git a/tests/imfile-endregex-timeout-none-polling.sh b/tests/imfile-endregex-timeout-none-polling.sh
new file mode 100755
index 0000000..de34de5
--- /dev/null
+++ b/tests/imfile-endregex-timeout-none-polling.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+if [ $(uname) = "SunOS" ] ; then
+ echo "Solaris: FIX ME"
+ exit 77
+fi
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile"
+ mode="polling"
+ pollingInterval="2"
+ )
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ PersistStateInterval="1"
+ startmsg.regex="^[^ ]")
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup
+
+# we need to sleep a bit between writes to give imfile a chance
+# to pick up the data (IN MULTIPLE ITERATIONS!)
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+./msleep 5000 # wait 5 seconds - this shall cause a timeout
+echo ' msgnum:2
+ msgnum:3' >> $RSYSLOG_DYNNAME.input
+# the next line terminates our test. It is NOT written to the output file,
+# as imfile waits whether or not there is a follow-up line that it needs
+# to combine.
+echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input
+./msleep 200
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+echo 'HEADER msgnum:0\\n msgnum:1\\n msgnum:2\\n msgnum:3' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid multiline message generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi;
+
+exit_test
diff --git a/tests/imfile-endregex-timeout-none.sh b/tests/imfile-endregex-timeout-none.sh
new file mode 100755
index 0000000..7554c27
--- /dev/null
+++ b/tests/imfile-endregex-timeout-none.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+echo ======================================================================
+echo [imfile-endregex-timeout-none.sh]
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ PersistStateInterval="1"
+ startmsg.regex="^[^ ]")
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup
+
+# we need to sleep a bit between writes to give imfile a chance
+# to pick up the data (IN MULTIPLE ITERATIONS!)
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+./msleep 5000 # wait 5 seconds - this shall cause a timeout
+echo ' msgnum:2
+ msgnum:3' >> $RSYSLOG_DYNNAME.input
+# the next line terminates our test. It is NOT written to the output file,
+# as imfile waits whether or not there is a follow-up line that it needs
+# to combine.
+echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input
+./msleep 200
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+printf 'HEADER msgnum:0\\\\n msgnum:1\\\\n msgnum:2\\\\n msgnum:3\n' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid multiline message generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi;
+
+exit_test
diff --git a/tests/imfile-endregex-timeout-polling.sh b/tests/imfile-endregex-timeout-polling.sh
new file mode 100755
index 0000000..8149ba8
--- /dev/null
+++ b/tests/imfile-endregex-timeout-polling.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+if [ $(uname) = "SunOS" ] ; then
+ echo "Solaris: FIX ME"
+ exit 77
+fi
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile"
+ mode="polling"
+ pollingInterval="2"
+ )
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ PersistStateInterval="1"
+ readTimeout="2"
+ startmsg.regex="^[^ ]")
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup
+
+# we need to sleep a bit between writes to give imfile a chance
+# to pick up the data (IN MULTIPLE ITERATIONS!)
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+./msleep 10000
+echo ' msgnum:2
+ msgnum:3' >> $RSYSLOG_DYNNAME.input
+# the next line terminates our test. It is NOT written to the output file,
+# as imfile waits whether or not there is a follow-up line that it needs
+# to combine.
+echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input
+./msleep 2000
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+echo 'HEADER msgnum:0\\n msgnum:1
+HEADER msgnum:2\\n msgnum:3' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid multiline message generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi;
+
+exit_test
diff --git a/tests/imfile-endregex-timeout-with-shutdown-polling.sh b/tests/imfile-endregex-timeout-with-shutdown-polling.sh
new file mode 100755
index 0000000..662fe70
--- /dev/null
+++ b/tests/imfile-endregex-timeout-with-shutdown-polling.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export IMFILECHECKTIMEOUT="60"
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile" mode="polling" pollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ PersistStateInterval="1"
+ readTimeout="3"
+ startmsg.regex="^[^ ]")
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup
+
+# we need to sleep a bit between writes to give imfile a chance
+# to pick up the data (IN MULTIPLE ITERATIONS!)
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+content_check_with_count 'msgnum:0
+ msgnum:1' 1 $IMFILECHECKTIMEOUT
+echo ' msgnum:2
+ msgnum:3' >> $RSYSLOG_DYNNAME.input
+
+# we now do a stop and restart of rsyslog. This checks that everything
+# works across restarts.
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+#echo DROPPING YOU TO BASH!
+#bash
+
+startup
+
+# new data
+echo ' msgnum:4' >> $RSYSLOG_DYNNAME.input
+content_check_with_count 'msgnum:2
+ msgnum:3
+ msgnum:4' 1 $IMFILECHECKTIMEOUT
+
+echo ' msgnum:5
+ msgnum:6' >> $RSYSLOG_DYNNAME.input
+content_check_with_count 'msgnum:5
+ msgnum:6' 1 $IMFILECHECKTIMEOUT
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+exit_test
diff --git a/tests/imfile-endregex-timeout-with-shutdown.sh b/tests/imfile-endregex-timeout-with-shutdown.sh
new file mode 100755
index 0000000..a33fce3
--- /dev/null
+++ b/tests/imfile-endregex-timeout-with-shutdown.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify-only
+export IMFILECHECKTIMEOUT="90"
+
+mkdir ${RSYSLOG_DYNNAME}.statefiles
+touch $RSYSLOG_DYNNAME.input # prevent misleading rsyslog diagnostic on startup
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile" timeoutGranularity="1"
+ statefile.Directory="'${RSYSLOG_DYNNAME}'.statefiles")
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:"
+ PersistStateInterval="1" readTimeout="2" startmsg.regex="^[^ ]")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action( type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+# we need to sleep a bit between writes to give imfile a chance
+# to pick up the data (IN MULTIPLE ITERATIONS!)
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+content_check_with_count "msgnum:0
+ msgnum:1" 1 $IMFILECHECKTIMEOUT
+echo ' msgnum:2
+ msgnum:3' >> $RSYSLOG_DYNNAME.input
+
+# we now do a stop and restart of rsyslog. This checks that everything
+# works across restarts.
+shutdown_when_empty
+wait_shutdown
+
+# re-start (so we read persisted state file)
+startup
+
+# new data
+echo ' msgnum:4' >> $RSYSLOG_DYNNAME.input
+echo INPUT FILE NOW: ; cat -n $RSYSLOG_DYNNAME.input
+content_check_with_count "msgnum:2
+ msgnum:3
+ msgnum:4" 1 $IMFILECHECKTIMEOUT
+
+echo ' msgnum:5
+ msgnum:6' >> $RSYSLOG_DYNNAME.input
+echo INPUT FILE NOW: ; cat -n $RSYSLOG_DYNNAME.input
+content_check_with_count "msgnum:5
+ msgnum:6" 1 $IMFILECHECKTIMEOUT
+
+
+# the next line terminates our test. It is NOT written to the output file,
+# as imfile waits whether or not there is a follow-up line that it needs
+# to combine.
+echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input
+
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/imfile-endregex-timeout.sh b/tests/imfile-endregex-timeout.sh
new file mode 100755
index 0000000..a08301c
--- /dev/null
+++ b/tests/imfile-endregex-timeout.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify-only
+export IMFILECHECKTIMEOUT="60"
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile" timeoutGranularity="1")
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:"
+ PersistStateInterval="1" readTimeout="2" startmsg.regex="^[^ ]")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+
+# we need to sleep a bit between writes to give imfile a chance
+# to pick up the data (IN MULTIPLE ITERATIONS!)
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+content_check_with_count "msgnum:0
+ msgnum:1" 1 $IMFILECHECKTIMEOUT
+
+echo ' msgnum:2
+ msgnum:3' >> $RSYSLOG_DYNNAME.input
+content_check_with_count "msgnum:2
+ msgnum:3" 1 $IMFILECHECKTIMEOUT
+
+# the next line terminates our test. It is NOT written to the output file,
+# as imfile waits whether or not there is a follow-up line that it needs
+# to combine.
+echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input
+
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/imfile-endregex-vg.sh b/tests/imfile-endregex-vg.sh
new file mode 100755
index 0000000..394ac9f
--- /dev/null
+++ b/tests/imfile-endregex-vg.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ startmsg.regex="^[^ ]")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup_vg
+
+# write the beginning of the file
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input
+
+wait_file_lines $RSYSLOG_OUT_LOG 1
+
+# write some more lines (see https://github.com/rsyslog/rsyslog/issues/144)
+echo 'msgnum:3
+ msgnum:4' >> $RSYSLOG_DYNNAME.input
+echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input # this one shouldn't be written to the output file because of ReadMode 2
+
+wait_file_lines $RSYSLOG_OUT_LOG 3
+
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+## check if we have the correct number of messages
+NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null)
+
+if [ -z $NUMLINES ]; then
+ echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+else
+ if [ ! $NUMLINES -eq 3 ]; then
+ echo "ERROR: expecting 3 headers, got $NUMLINES"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+fi
+
+## check if all the data we expect to get in the file is there
+
+for i in {1..4}; do
+ grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1
+ if [ ! $? -eq 0 ]; then
+ echo "ERROR: expecting the string 'msgnum:$i', it's not there"
+ error_exit 1
+ fi
+done
+
+exit_test
diff --git a/tests/imfile-endregex.sh b/tests/imfile-endregex.sh
new file mode 100755
index 0000000..4984c52
--- /dev/null
+++ b/tests/imfile-endregex.sh
@@ -0,0 +1,86 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# This test mimics the test imfile-readmode2.sh, but works via
+# endmsg.regex. It's kind of a base test for the regex functionality.
+echo ======================================================================
+echo [imfile-endregex.sh]
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ startmsg.regex="^[^ ]")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup
+
+# write the beginning of the file
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input
+
+# sleep a little to give rsyslog a chance to begin processing
+sleep 1
+
+# write some more lines (see https://github.com/rsyslog/rsyslog/issues/144)
+echo 'msgnum:3
+ msgnum:4' >> $RSYSLOG_DYNNAME.input
+echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input # this one shouldn't be written to the output file because of ReadMode 2
+
+# give it time to finish
+sleep 1
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+# give it time to write the output file
+sleep 1
+
+## check if we have the correct number of messages
+
+NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null)
+
+if [ -z $NUMLINES ]; then
+ echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+else
+ if [ ! $NUMLINES -eq 3 ]; then
+ echo "ERROR: expecting 3 headers, got $NUMLINES"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+ fi
+fi
+
+## check if all the data we expect to get in the file is there
+
+for i in {1..4}; do
+ grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1
+ if [ ! $? -eq 0 ]; then
+ echo "ERROR: expecting the string 'msgnum:$i', it's not there"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+ fi
+done
+
+## if we got here, all is good :)
+
+exit_test
diff --git a/tests/imfile-error-not-repeated.sh b/tests/imfile-error-not-repeated.sh
new file mode 100755
index 0000000..cc2b06e
--- /dev/null
+++ b/tests/imfile-error-not-repeated.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# add 2017-04-28 by Pascal Withopf, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile" mode="polling" pollingInterval="1")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="tag1" ruleset="ruleset1")
+
+template(name="tmpl1" type="string" string="%msg%\n")
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="tmpl1")
+}
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)
+'
+startup
+./msleep 3000
+
+echo 'testmessage1
+testmessage2
+testmessage3' > $RSYSLOG_DYNNAME.input
+
+./msleep 2000
+rm ./'$RSYSLOG_DYNNAME'.input
+./msleep 3000
+shutdown_when_empty
+wait_shutdown
+
+grep "file.*$RSYSLOG_DYNNAME.input.*No such file or directory" ${RSYSLOG2_OUT_LOG} > /dev/null
+if [ $? -ne 0 ]; then
+ echo "FAIL: expected error message from missing input file not found. ${RSYSLOG2_OUT_LOG} is:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi
+
+if [ $(grep "No such file or directory" ${RSYSLOG2_OUT_LOG} | wc -l) -ne 1 ]; then
+ echo "FAIL: expected error message is put out multiple times. ${RSYSLOG2_OUT_LOG} is:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi
+
+echo 'testmessage1
+testmessage2
+testmessage3' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imfile-escapelf.replacement-empty.sh b/tests/imfile-escapelf.replacement-empty.sh
new file mode 100755
index 0000000..759c8a9
--- /dev/null
+++ b/tests/imfile-escapelf.replacement-empty.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Written in 2019 by Rainer Gerhards
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile" ruleset="output" escapelf.replacement=""
+ File="./'$RSYSLOG_DYNNAME'.input" tag="file:" startmsg.regex="^msg")
+
+template(name="outfmt" type="string" string="%msg%\n")
+ruleset(name="output") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+# make sure file exists when rsyslog starts up
+echo 'msg 1 part 1
+ msg 1 part 2
+msg 2
+msg INVISIBLE by design' > $RSYSLOG_DYNNAME.input
+startup
+export NUMMESSAGES=2
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='msg 1 part 1 msg 1 part 2
+msg 2'
+cmp_exact
+exit_test
diff --git a/tests/imfile-escapelf.replacement.sh b/tests/imfile-escapelf.replacement.sh
new file mode 100755
index 0000000..6039947
--- /dev/null
+++ b/tests/imfile-escapelf.replacement.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Written in 2019 by Rainer Gerhards
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile" ruleset="output" escapelf.replacement="[LF]"
+ File="./'$RSYSLOG_DYNNAME'.input" tag="file:" startmsg.regex="^msg")
+
+template(name="outfmt" type="string" string="%msg%\n")
+ruleset(name="output") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+# make sure file exists when rsyslog starts up
+echo 'msg 1 part 1
+ msg 1 part 2
+msg 2
+msg INVISIBLE by design' > $RSYSLOG_DYNNAME.input
+startup
+export NUMMESSAGES=2
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='msg 1 part 1[LF] msg 1 part 2
+msg 2'
+cmp_exact
+exit_test
diff --git a/tests/imfile-file-not-found-error.sh b/tests/imfile-file-not-found-error.sh
new file mode 100755
index 0000000..029a33c
--- /dev/null
+++ b/tests/imfile-file-not-found-error.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# add 2017-04-28 by Pascal Withopf, released under ASL 2.0
+echo [imfile-file-not-found-error.sh]
+. $srcdir/diag.sh check-inotify
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="tag1" ruleset="ruleset1")
+
+template(name="tmpl1" type="string" string="%msg%\n")
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="tmpl1")
+}
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)
+'
+startup
+./msleep 2000
+
+echo 'testmessage1
+testmessage2
+testmessage3' > $RSYSLOG_DYNNAME.input
+
+./msleep 2000
+shutdown_when_empty
+wait_shutdown
+
+grep "file.*$RSYSLOG_DYNNAME.input.*No such file or directory" ${RSYSLOG2_OUT_LOG} > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message from missing input file not found. ${RSYSLOG2_OUT_LOG} is:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi
+
+printf 'testmessage1
+testmessage2
+testmessage3\n' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imfile-fileNotFoundError-parameter.sh b/tests/imfile-fileNotFoundError-parameter.sh
new file mode 100755
index 0000000..e890b72
--- /dev/null
+++ b/tests/imfile-fileNotFoundError-parameter.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+echo [imfile-file-not-found-error.sh]
+. $srcdir/diag.sh check-inotify
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile" File="testsuites/NotExistingInputFile" Tag="tag1" fileNotFoundError="off")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+grep "error*file*NotExistingInputFile*No such file or directory" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -eq 0 ]; then
+ echo
+ echo "FAIL: error message from missing input file found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imfile-freshStartTail1.sh b/tests/imfile-freshStartTail1.sh
new file mode 100755
index 0000000..ed0f3fb
--- /dev/null
+++ b/tests/imfile-freshStartTail1.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# add 2018-05-17 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile" freshStartTail="on" Tag="pro"
+ File="'$RSYSLOG_DYNNAME'.input")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:syslogtag, contains, "pro" action(type="omfile" File=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+'
+startup
+
+echo '{ "id": "jinqiao1"}' > $RSYSLOG_DYNNAME.input
+./msleep 2000
+echo '{ "id": "jinqiao2"}' >> $RSYSLOG_DYNNAME.input
+
+shutdown_when_empty
+wait_shutdown
+
+echo '{ "id": "jinqiao1"}
+{ "id": "jinqiao2"}' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imfile-freshStartTail2.sh b/tests/imfile-freshStartTail2.sh
new file mode 100755
index 0000000..802b712
--- /dev/null
+++ b/tests/imfile-freshStartTail2.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# add 2018-05-17 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+export IMFILECHECKTIMEOUT="60"
+
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile" freshStartTail="on" Tag="pro"
+ File="'$RSYSLOG_DYNNAME'.input.*")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:syslogtag, contains, "pro" action(type="omfile" File=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+'
+startup
+
+echo '{ "id": "jinqiao1"}' > $RSYSLOG_DYNNAME.input.a
+content_check_with_count '{ "id": "jinqiao1"}' 1 $IMFILECHECKTIMEOUT
+
+echo '{ "id": "jinqiao2"}' >> $RSYSLOG_DYNNAME.input.a
+content_check_with_count '{ "id": "jinqiao2"}' 1 $IMFILECHECKTIMEOUT
+
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/imfile-freshStartTail3.sh b/tests/imfile-freshStartTail3.sh
new file mode 100755
index 0000000..0e651b7
--- /dev/null
+++ b/tests/imfile-freshStartTail3.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# add 2018-05-17 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile" freshStartTail="on" Tag="pro"
+ File="'$RSYSLOG_DYNNAME'.input")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:syslogtag, contains, "pro" action(type="omfile" File=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+'
+
+echo '{ "id": "jinqiao1"}' > $RSYSLOG_DYNNAME.input
+startup
+./msleep 2000
+echo '{ "id": "jinqiao2"}' >> $RSYSLOG_DYNNAME.input
+
+shutdown_when_empty
+wait_shutdown
+
+echo '{ "id": "jinqiao2"}' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imfile-growing-file-id.sh b/tests/imfile-growing-file-id.sh
new file mode 100755
index 0000000..2649c8b
--- /dev/null
+++ b/tests/imfile-growing-file-id.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under GPLv3
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify-only
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+module(load="../plugins/imfile/.libs/imfile" mode="inotify" PollingInterval="1")
+
+/* Filter out busy debug output */
+global( debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"])
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:" Severity="error" Facility="local7" addMetadata="on")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+
+# generate small input file - state file must be inode only
+./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input
+ls -li $RSYSLOG_DYNNAME.input
+
+echo "STEP 1 - small input"
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+echo "STEP 2 - still small input"
+# add a bit to input file, but state file must still be inode only
+./inputfilegen -m 1 -i1 >> $RSYSLOG_DYNNAME.input
+ls -li $RSYSLOG_DYNNAME.input*
+if [ $(ls ${RSYSLOG_DYNNAME}.spool/* | wc -l) -ne 1 ]; then
+ echo FAIL: more than one state file in work directory:
+ ls -l ${RSYSLOG_DYNNAME}.spool
+ error_exit 1
+fi
+
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+echo "STEP 3 - larger input, hash shall be used"
+./inputfilegen -m 998 -i 2 >> $RSYSLOG_DYNNAME.input
+ls -li $RSYSLOG_DYNNAME.input*
+echo ls ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+if [ $(ls ${RSYSLOG_DYNNAME}.spool/* | wc -l) -ne 1 ]; then
+ echo FAIL: more than one state file in work directory:
+ ls -l ${RSYSLOG_DYNNAME}.spool
+ error_exit 1
+fi
+
+
+echo "STEP 4 - append to larger input, hash state file must now be found"
+./inputfilegen -m 1000 -i 1000 >> $RSYSLOG_DYNNAME.input
+ls -li $RSYSLOG_DYNNAME.input*
+echo ls ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+if [ $(ls ${RSYSLOG_DYNNAME}.spool/* | wc -l) -ne 1 ]; then
+ echo FAIL: more than one state file in work directory:
+ ls -l ${RSYSLOG_DYNNAME}.spool
+ error_exit 1
+fi
+
+seq_check 0 1999
+exit_test
diff --git a/tests/imfile-ignore-old-file-1.sh b/tests/imfile-ignore-old-file-1.sh
new file mode 100755
index 0000000..9ae660c
--- /dev/null
+++ b/tests/imfile-ignore-old-file-1.sh
@@ -0,0 +1,37 @@
+#! /bin/bash
+# Don't read a file with old timestamp
+echo [imfile-ignore-old-file-1.sh]
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ ignoreolderthan="604800"
+ Tag="file:"
+ ruleset="ruleset")
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+
+# create a log for testing
+./inputfilegen -m 1000 > ${RSYSLOG_DYNNAME}.input
+
+touch -m -t 201806010000.00 ./${RSYSLOG_DYNNAME}.input
+
+startup
+
+# shut down rsyslogd when done processing messages
+shutdown_when_empty
+# we need to wait until rsyslogd is finished!
+wait_shutdown
+
+if ls ${RSYSLOG_OUT_LOG} > /dev/null; then
+ echo "FAIL: rsyslog.out.log isn't expected to be generated!"
+ exit 1
+fi
+
+exit_test
diff --git a/tests/imfile-ignore-old-file-2.sh b/tests/imfile-ignore-old-file-2.sh
new file mode 100755
index 0000000..d69cb5e
--- /dev/null
+++ b/tests/imfile-ignore-old-file-2.sh
@@ -0,0 +1,43 @@
+#! /bin/bash
+# Don't read a file with old timestamp
+# touch the file, then read it
+echo [imfile-ignore-old-file-2.sh]
+. $srcdir/diag.sh check-inotify
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ ignoreolderthan="604800"
+ Tag="file:"
+ ruleset="ruleset")
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+
+# create a log for testing
+./inputfilegen -m 1000 > ${RSYSLOG_DYNNAME}.input
+touch -m -t 201806010000.00 ./${RSYSLOG_DYNNAME}.input
+startup
+# sleep a little to give rsyslog a chance to begin processing
+./msleep 500
+
+if ls ${RSYSLOG_OUT_LOG} > /dev/null; then
+ echo "FAIL: rsyslog.out.log isn't expected to be generated!"
+ exit 1
+fi
+
+# change timestamp
+./inputfilegen -m 1000 -i 1000 >> ${RSYSLOG_DYNNAME}.input
+ls -l ./${RSYSLOG_DYNNAME}.input
+./msleep 500
+# shut down rsyslogd when done processing messages
+shutdown_when_empty
+# we need to wait until rsyslogd is finished!
+wait_shutdown
+# check log file
+seq_check 0 1999
+exit_test
diff --git a/tests/imfile-ignore-old-file-3.sh b/tests/imfile-ignore-old-file-3.sh
new file mode 100755
index 0000000..e74e3a4
--- /dev/null
+++ b/tests/imfile-ignore-old-file-3.sh
@@ -0,0 +1,34 @@
+#! /bin/bash
+# Multiple files with different timestamp, ignore those files with old timestamp
+echo [imfile-ignore-old-file-3.sh]
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.ignore3.*"
+ ignoreolderthan="604800"
+ Tag="file:"
+ ruleset="ruleset")
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+# create log files for testing
+./inputfilegen -m 1000 > ${RSYSLOG_DYNNAME}.input.ignore3.1
+touch -m -t 201806010000.00 ./${RSYSLOG_DYNNAME}.input.ignore3.1
+
+./inputfilegen -m 1000 -i 1000 > ${RSYSLOG_DYNNAME}.input.ignore3.2
+
+startup
+# sleep a little to give rsyslog a chance to begin processing
+./msleep 500
+# shut down rsyslogd when done processing messages
+shutdown_when_empty
+# we need to wait until rsyslogd is finished!
+wait_shutdown
+# check log file
+seq_check 1000 1999
+exit_test
diff --git a/tests/imfile-ignore-old-file-4.sh b/tests/imfile-ignore-old-file-4.sh
new file mode 100755
index 0000000..e96d5dc
--- /dev/null
+++ b/tests/imfile-ignore-old-file-4.sh
@@ -0,0 +1,31 @@
+#! /bin/bash
+# set ignoreolderthan to zero
+echo [imfile-ignore-old-file-4.sh]
+. $srcdir/diag.sh check-inotify
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ ignoreolderthan="0"
+ Tag="file:"
+ ruleset="ruleset")
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+# create a log for testing
+./inputfilegen -m 1000 > ${RSYSLOG_DYNNAME}.input
+touch -m -t 201806010000.00 ./${RSYSLOG_DYNNAME}.input
+startup
+# sleep a little to give rsyslog a chance to begin processing
+./msleep 500
+# shut down rsyslogd when done processing messages
+shutdown_when_empty
+# we need to wait until rsyslogd is finished!
+wait_shutdown
+# check log file
+seq_check 0 999
+exit_test
diff --git a/tests/imfile-ignore-old-file-5.sh b/tests/imfile-ignore-old-file-5.sh
new file mode 100755
index 0000000..66bd910
--- /dev/null
+++ b/tests/imfile-ignore-old-file-5.sh
@@ -0,0 +1,47 @@
+#! /bin/bash
+# [polling mode] Don't read a file with old timestamp
+# touch the file, then read it
+
+echo [imfile-ignore-old-file-5.sh]
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile"
+ mode="polling"
+ pollingInterval="1"
+ )
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ ignoreolderthan="604800"
+ Tag="file:"
+ ruleset="ruleset")
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+# create a log for testing
+./inputfilegen -m 1000 > $RSYSLOG_DYNNAME.input
+touch -m -t 201806010000.00 ./$RSYSLOG_DYNNAME.input
+
+startup
+# sleep a little to give rsyslog a chance to begin processing
+./msleep 500
+
+if ls ${RSYSLOG_OUT_LOG} > /dev/null; then
+ echo "FAIL: rsyslog.out.log isn't expected to be generated!"
+ exit 1
+fi
+
+# change timestamp
+./inputfilegen -m 1000 -i 1000 >> $RSYSLOG_DYNNAME.input
+ls -l ./$RSYSLOG_DYNNAME.input
+
+./msleep 1000
+# shut down rsyslogd when done processing messages
+shutdown_when_empty
+# we need to wait until rsyslogd is finished!
+wait_shutdown
+# check log file
+seq_check 0 1999
+exit_test
diff --git a/tests/imfile-ignore-old-file-6.sh b/tests/imfile-ignore-old-file-6.sh
new file mode 100755
index 0000000..8bf92f0
--- /dev/null
+++ b/tests/imfile-ignore-old-file-6.sh
@@ -0,0 +1,42 @@
+#! /bin/bash
+# [polling mode] Multiple files with different timestamp, ignore those files with old timestamp
+
+echo [imfile-ignore-old-file-6.sh]
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile"
+ mode="polling"
+ pollingInterval="2"
+ )
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.1"
+ ignoreolderthan="604800"
+ Tag="file:"
+ ruleset="ruleset")
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.2"
+ ignoreolderthan="604800"
+ Tag="file:"
+ ruleset="ruleset")
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+# create log files for testing
+./inputfilegen -m 1000 > $RSYSLOG_DYNNAME.input.1
+touch -m -t 201806010000.00 ./$RSYSLOG_DYNNAME.input.1
+./inputfilegen -m 1000 -i 1000 > $RSYSLOG_DYNNAME.input.2
+
+startup
+# sleep a little to give rsyslog a chance to begin processing
+./msleep 500
+# shut down rsyslogd when done processing messages
+shutdown_when_empty
+# we need to wait until rsyslogd is finished!
+wait_shutdown
+# check log file
+seq_check 1000 1999
+exit_test
diff --git a/tests/imfile-ignore-old-file-7.sh b/tests/imfile-ignore-old-file-7.sh
new file mode 100755
index 0000000..db01aad
--- /dev/null
+++ b/tests/imfile-ignore-old-file-7.sh
@@ -0,0 +1,56 @@
+#! /bin/bash
+# Read a file and ignore another one from an old symlink
+echo [imfile-ignore-old-file-7.sh]
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile"
+ File="./symlink/'$RSYSLOG_DYNNAME'.input.ignore3.*"
+ ignoreolderthan="86400"
+ Tag="file:"
+ ruleset="ruleset")
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+
+# create a log for testing
+mkdir ./source
+./inputfilegen -m 1000 > ./source/${RSYSLOG_DYNNAME}.input.ignore3.1
+touch -m -t 201806010000.00 ./source/${RSYSLOG_DYNNAME}.input.ignore3.1
+
+./inputfilegen -m 1000 -i 1000 > ./source/${RSYSLOG_DYNNAME}.input.ignore3.2
+
+echo "source file date: "
+ls -alth ./source/${RSYSLOG_DYNNAME}.input.ignore3.* #DEBUG
+
+# create symlink
+ln -sf ./source/ ./symlink
+
+# apply old date to symlink
+touch -h -t 201806010000.00 ./symlink
+
+echo "symlink date"
+ls -alth ./symlink #DEBUG
+
+echo "File dates:"
+ls -alth ./symlink/${RSYSLOG_DYNNAME}.input.ignore3.* #DEBUG
+
+startup
+# sleep a little to give rsyslog a chance to begin processing
+./msleep 1000
+# shut down rsyslogd when done processing messages
+shutdown_when_empty
+# we need to wait until rsyslogd is finished!
+wait_shutdown
+# check log file
+seq_check 1000 1999
+
+# cleanup
+unlink ./symlink
+rm -rf ./source
+
+exit_test
diff --git a/tests/imfile-logrotate-async.sh b/tests/imfile-logrotate-async.sh
new file mode 100755
index 0000000..b6d8315
--- /dev/null
+++ b/tests/imfile-logrotate-async.sh
@@ -0,0 +1,108 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. $srcdir/diag.sh check-inotify-only
+. ${srcdir:=.}/diag.sh init
+check_command_available logrotate
+export NUMMESSAGES=10000
+export RETRIES=50
+
+# Uncomment fdor debuglogs
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog"
+
+# Write logrotate config file
+echo '"./'$RSYSLOG_DYNNAME'.input*.log"
+{
+ #daily
+ rotate 60
+ missingok
+ notifempty
+ sharedscripts
+ postrotate
+ kill -HUP $(cat '$RSYSLOG_DYNNAME'.inputfilegen_pid)
+ endscript
+ #olddir /logs/old
+
+}' > $RSYSLOG_DYNNAME.logrotate
+
+
+generate_conf
+add_conf '
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+
+global( debug.whitelist="on"
+ debug.files=["imfile.c", "stream.c"]
+ )
+
+module(load="../plugins/imfile/.libs/imfile" mode="inotify" PollingInterval="2")
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input*.log" Tag="file:"
+ Severity="error" Facility="local7" addMetadata="on" reopenOnTruncate="on")
+
+$template outfmt,"%msg:F,58:2%\n"
+if $msg contains "msgnum:" then
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+./inputfilegen -m $NUMMESSAGES -S 5 -B 100 -I 1000 -f $RSYSLOG_DYNNAME.input.log &
+INPUTFILEGEN_PID=$!
+echo "$INPUTFILEGEN_PID" > $RSYSLOG_DYNNAME.inputfilegen_pid
+
+./msleep 1
+logrotate --state $RSYSLOG_DYNNAME.logrotate.state -f $RSYSLOG_DYNNAME.logrotate
+./msleep 20
+echo ======================:
+echo ROTATE 1 INPUT FILES:
+ls -li $RSYSLOG_DYNNAME.input*
+logrotate --state $RSYSLOG_DYNNAME.logrotate.state -f $RSYSLOG_DYNNAME.logrotate
+./msleep 20
+echo ======================:
+echo ROTATE 2 INPUT FILES:
+ls -li $RSYSLOG_DYNNAME.input*
+logrotate --state $RSYSLOG_DYNNAME.logrotate.state -f $RSYSLOG_DYNNAME.logrotate
+echo ======================:
+echo ROTATE 3 INPUT FILES:
+ls -li $RSYSLOG_DYNNAME.input*
+echo ======================:
+echo ls ${RSYSLOG_DYNNAME}.spool:
+ls -li ${RSYSLOG_DYNNAME}.spool
+echo ======================:
+echo FINAL INPUT FILES:
+ls -li $RSYSLOG_DYNNAME.input*
+
+# generate more input after logrotate into new logfile
+#./inputfilegen -m $TESTMESSAGES -i $TESTMESSAGES >> $RSYSLOG_DYNNAME.input.1.log
+#ls -l $RSYSLOG_DYNNAME.input*
+
+#msgcount=$((2* TESTMESSAGES))
+#wait_file_lines $RSYSLOG_OUT_LOG $msgcount $RETRIES
+# Output extra information
+./msleep 1000
+echo ======================:
+echo LINES: $(wc -l $RSYSLOG_DYNNAME.input.log)
+echo TAIL $RSYSLOG_DYNNAME.input.log:
+tail $RSYSLOG_DYNNAME.input.log
+echo ""
+echo LINES: $(wc -l $RSYSLOG_DYNNAME.input.log.1)
+echo TAIL $RSYSLOG_DYNNAME.input.log.1:
+tail $RSYSLOG_DYNNAME.input.log.1
+echo ""
+echo LINES: $(wc -l $RSYSLOG_DYNNAME.input.log.2)
+echo TAIL $RSYSLOG_DYNNAME.input.log.2:
+tail $RSYSLOG_DYNNAME.input.log.2
+echo ""
+echo LINES: $(wc -l $RSYSLOG_DYNNAME.inpt.log.3)
+echo TAIL $RSYSLOG_DYNNAME.input.log.3:
+tail $RSYSLOG_DYNNAME.input.log.3
+echo ""
+wait_file_lines
+
+touch $RSYSLOG_DYNNAME.input.log
+./msleep 1000
+
+shutdown_when_empty
+wait_shutdown
+seq_check
+#seq_check 0 $TESTMESSAGESFULL
+exit_test
diff --git a/tests/imfile-logrotate-copytruncate.sh b/tests/imfile-logrotate-copytruncate.sh
new file mode 100755
index 0000000..74643a4
--- /dev/null
+++ b/tests/imfile-logrotate-copytruncate.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. $srcdir/diag.sh check-inotify-only
+. ${srcdir:=.}/diag.sh init
+check_command_available logrotate
+
+export TESTMESSAGES=10000
+export RETRIES=50
+export TESTMESSAGESFULL=19999
+
+generate_conf
+add_conf '
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+
+/* Filter out busy debug output */
+global(
+ debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+ )
+
+module( load="../plugins/imfile/.libs/imfile"
+ mode="inotify"
+ PollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.*.log"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+ reopenOnTruncate="on"
+)
+
+$template outfmt,"%msg:F,58:2%\n"
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+
+# Write logrotate config file
+echo '"./'$RSYSLOG_DYNNAME'.input.*.log"
+{
+ rotate 7
+ create
+ daily
+ missingok
+ notifempty
+ compress
+ copytruncate
+}' > $RSYSLOG_DYNNAME.logrotate
+
+# generate input file first.
+./inputfilegen -m $TESTMESSAGES > $RSYSLOG_DYNNAME.input.1.log
+ls -l $RSYSLOG_DYNNAME.input*
+
+startup
+
+# Wait until testmessages are processed by imfile!
+wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGES $RETRIES
+
+# Logrotate on logfile
+logrotate --state $RSYSLOG_DYNNAME.logrotate.state -f $RSYSLOG_DYNNAME.logrotate
+
+# generate more input after logrotate into new logfile
+./inputfilegen -m $TESTMESSAGES -i $TESTMESSAGES >> $RSYSLOG_DYNNAME.input.1.log
+ls -l $RSYSLOG_DYNNAME.input*
+echo ls ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+msgcount=$((2* TESTMESSAGES))
+wait_file_lines $RSYSLOG_OUT_LOG $msgcount $RETRIES
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+seq_check 0 $TESTMESSAGESFULL
+exit_test
diff --git a/tests/imfile-logrotate-multiple.sh b/tests/imfile-logrotate-multiple.sh
new file mode 100755
index 0000000..e63a308
--- /dev/null
+++ b/tests/imfile-logrotate-multiple.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. $srcdir/diag.sh check-inotify-only
+. ${srcdir:=.}/diag.sh init
+check_command_available logrotate
+
+export IMFILEROTATES="10"
+export TESTMESSAGES=10000
+export TESTMESSAGESFULL=$((IMFILEROTATES * TESTMESSAGES-1))
+
+generate_conf
+add_conf '
+global(
+ workDirectory="'$RSYSLOG_DYNNAME'.spool"
+ /* Filter out busy debug output */
+ debug.whitelist="off"
+ debug.files=["omfile.c", "queue.c", "rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+ )
+
+module(load="../plugins/imfile/.libs/imfile" mode="inotify")
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:" Severity="error" Facility="local7" addMetadata="on")
+
+$template outfmt,"%msg:F,58:2%\n"
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+
+# Write logrotate config file
+echo '"./'$RSYSLOG_DYNNAME'.input"
+{
+ create
+ daily
+ missingok
+ rotate 14
+ notifempty
+ compress
+ delaycompress
+}' > $RSYSLOG_DYNNAME.logrotate
+
+
+display_file() {
+ printf '\nFILE %s content:\n' $1
+ cat -n $1
+}
+
+startup
+
+TESTMESSAGESSTART=0
+for i in $(seq 1 $IMFILEROTATES);
+do
+ #printf 'PRESS ENTER TO CONTINUE\n'
+ #read
+ printf '\n\nNEW RUN:\n'
+
+ ./inputfilegen -m $TESTMESSAGES -i $TESTMESSAGESSTART > $RSYSLOG_DYNNAME.input
+
+ ls -li $RSYSLOG_DYNNAME.input*
+ echo ls ${RSYSLOG_DYNNAME}.spool:
+ ls -li ${RSYSLOG_DYNNAME}.spool
+ echo STATE FILE CONTENT:
+ shopt -s extglob
+ for filename in "$RSYSLOG_DYNNAME.spool"/imfile-state:*; do display_file $filename; done
+
+ # Wait until testmessages are processed by imfile!
+ msgcount=$((i * TESTMESSAGES-1))
+ # echo "TESTMESSAGESSTART: $TESTMESSAGESSTART - TotalMsgCount: $msgcount"
+ wait_file_lines $RSYSLOG_OUT_LOG $msgcount $RETRIES
+
+ # Logrotate on logfile
+ logrotate --state $RSYSLOG_DYNNAME.logrotate.state -f $RSYSLOG_DYNNAME.logrotate
+
+ TESTMESSAGESSTART=$((TESTMESSAGESSTART+TESTMESSAGES))
+done
+
+
+shutdown_when_empty
+wait_shutdown
+seq_check 0 $TESTMESSAGESFULL
+exit_test
diff --git a/tests/imfile-logrotate-nocopytruncate.sh b/tests/imfile-logrotate-nocopytruncate.sh
new file mode 100755
index 0000000..31e80be
--- /dev/null
+++ b/tests/imfile-logrotate-nocopytruncate.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. $srcdir/diag.sh check-inotify-only
+. ${srcdir:=.}/diag.sh init
+check_command_available logrotate
+
+export TESTMESSAGES=10000
+export RETRIES=50
+export TESTMESSAGESFULL=19999
+
+generate_conf
+add_conf '
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+
+/* Filter out busy debug output */
+global(
+ debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+ )
+
+module( load="../plugins/imfile/.libs/imfile"
+ mode="inotify"
+ PollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.*.log"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+
+$template outfmt,"%msg:F,58:2%\n"
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+
+# Write logrotate config file
+echo '"./'$RSYSLOG_DYNNAME'.input.*.log"
+{
+ rotate 7
+ create
+ daily
+ missingok
+ notifempty
+ compress
+ nocopytruncate
+}' > $RSYSLOG_DYNNAME.logrotate
+
+# generate input file first.
+./inputfilegen -m $TESTMESSAGES > $RSYSLOG_DYNNAME.input.1.log
+ls -l $RSYSLOG_DYNNAME.input*
+
+startup
+
+# Wait until testmessages are processed by imfile!
+wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGES $RETRIES
+
+# Logrotate on logfile
+logrotate --state $RSYSLOG_DYNNAME.logrotate.state -f $RSYSLOG_DYNNAME.logrotate
+
+# generate more input after logrotate into new logfile
+./inputfilegen -m $TESTMESSAGES -i $TESTMESSAGES >> $RSYSLOG_DYNNAME.input.1.log
+ls -l $RSYSLOG_DYNNAME.input*
+echo ls ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+msgcount=$((2* TESTMESSAGES))
+wait_file_lines $RSYSLOG_OUT_LOG $msgcount $RETRIES
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+seq_check 0 $TESTMESSAGESFULL
+exit_test
diff --git a/tests/imfile-logrotate.sh b/tests/imfile-logrotate.sh
new file mode 100755
index 0000000..5d9b238
--- /dev/null
+++ b/tests/imfile-logrotate.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. $srcdir/diag.sh check-inotify-only
+. ${srcdir:=.}/diag.sh init
+check_command_available logrotate
+
+export TESTMESSAGES=10000
+export RETRIES=50
+export TESTMESSAGESFULL=19999
+
+generate_conf
+add_conf '
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+
+/* Filter out busy debug output */
+global(
+ debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+ )
+
+module( load="../plugins/imfile/.libs/imfile"
+ mode="inotify"
+ PollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.*.log"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+
+$template outfmt,"%msg:F,58:2%\n"
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+
+# Write logrotate config file
+echo '"./'$RSYSLOG_DYNNAME'.input.*.log"
+{
+ rotate 7
+ create
+ daily
+ missingok
+ notifempty
+ compress
+}' > $RSYSLOG_DYNNAME.logrotate
+
+# generate input file first.
+./inputfilegen -m $TESTMESSAGES > $RSYSLOG_DYNNAME.input.1.log
+ls -l $RSYSLOG_DYNNAME.input*
+
+startup
+
+# Wait until testmessages are processed by imfile!
+wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGES $RETRIES
+
+# Logrotate on logfile
+logrotate --state $RSYSLOG_DYNNAME.logrotate.state -f $RSYSLOG_DYNNAME.logrotate
+
+# generate more input after logrotate into new logfile
+./inputfilegen -m $TESTMESSAGES -i $TESTMESSAGES >> $RSYSLOG_DYNNAME.input.1.log
+ls -l $RSYSLOG_DYNNAME.input*
+echo ls ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+msgcount=$((2* TESTMESSAGES))
+wait_file_lines $RSYSLOG_OUT_LOG $msgcount $RETRIES
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+seq_check 0 $TESTMESSAGESFULL
+exit_test
diff --git a/tests/imfile-old-state-file.sh b/tests/imfile-old-state-file.sh
new file mode 100755
index 0000000..5b92bbb
--- /dev/null
+++ b/tests/imfile-old-state-file.sh
@@ -0,0 +1,87 @@
+#!/bin/bash
+# this test checks that old (v1, pre 8.34.0) imfile state files are
+# properly read in. It is based on imfile-readmode2-with-persists.sh,
+# where the first part before the shutdown is removed, and an old state
+# file is populated. Note that in contrast to the original test the
+# initial set of lines from the input file is missing - this is
+# exactly what shall happen.
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# added 2018-03-29 by rgerhards
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ ReadMode="2")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+
+# do mock-up setup
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input
+
+# we need to patch the state file to match the current inode number
+inode=$(ls -i $RSYSLOG_DYNNAME.input|awk '{print $1}')
+leninode=${#inode}
+newline="+inode:2:${leninode}:${inode}:"
+
+sed s/+inode:2:7:4464465:/${newline}/ <$srcdir/testsuites/imfile-old-state-file_imfile-state_.-rsyslog.input > ${RSYSLOG_DYNNAME}.spool/imfile-state\:.-$RSYSLOG_DYNNAME.input
+printf "info: new input file: $(ls -i $RSYSLOG_DYNNAME.input)\n"
+printf "info: new inode line: ${newline}\n"
+printf "info: patched state file:\n"
+cat ${RSYSLOG_DYNNAME}.spool/imfile-state\:.-$RSYSLOG_DYNNAME.input
+
+startup
+
+echo 'msgnum:3
+ msgnum:4' >> $RSYSLOG_DYNNAME.input
+echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null)
+
+if [ -z $NUMLINES ]; then
+ echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+else
+ # note: we expect only 2 headers as the first file part if NOT processed!
+ if [ ! $NUMLINES -eq 2 ]; then
+ echo "ERROR: expecting 2 headers, got $NUMLINES"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+fi
+
+## check if all the data we expect to get in the file is there
+
+for i in {2..4}; do
+ grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1
+ if [ ! $? -eq 0 ]; then
+ echo "ERROR: expecting the string 'msgnum:$i', it's not there"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+done
+
+exit_test
diff --git a/tests/imfile-persist-state-1.sh b/tests/imfile-persist-state-1.sh
new file mode 100755
index 0000000..f3fe3ee
--- /dev/null
+++ b/tests/imfile-persist-state-1.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# added 2016-11-02 by rgerhards
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+
+module(load="../plugins/imfile/.libs/imfile")
+
+input( type="imfile"
+ file="./'$RSYSLOG_DYNNAME'.input"
+ tag="file:"
+ startmsg.regex="^msgnum"
+ PersistStateInterval="1"
+)
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+# generate input file first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+./inputfilegen -m5 -d4000 > $RSYSLOG_DYNNAME.input
+startup
+shutdown_when_empty
+wait_shutdown
+seq_check 0 3
+exit_test
diff --git a/tests/imfile-readmode0-vg.sh b/tests/imfile-readmode0-vg.sh
new file mode 100755
index 0000000..48440c5
--- /dev/null
+++ b/tests/imfile-readmode0-vg.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# Tests for processing of partial lines in read mode 0
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" ReadMode="0")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+
+printf 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+printf '\nmsgnum:2' >> $RSYSLOG_DYNNAME.input
+
+# sleep a little to give rsyslog a chance to process unterminated lines
+./msleep 500
+
+# write some more lines (see https://github.com/rsyslog/rsyslog/issues/144)
+printf 'msgnum:3
+ msgnum:4' >> $RSYSLOG_DYNNAME.input
+printf '\nmsgnum:5' >> $RSYSLOG_DYNNAME.input # this one shouldn't be written to the output file because of missing LF
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown_vg # we need to wait until rsyslogd is finished!
+check_exit_vg
+
+## check if we have the correct number of messages
+NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null)
+
+if [ -z $NUMLINES ]; then
+ echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+else
+ if [ ! $NUMLINES -eq 4 ]; then
+ echo "ERROR: expecting 4 headers, got $NUMLINES"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+fi
+
+## check if all the data we expect to get in the file is there
+for i in {1..4}; do
+ grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1
+ if [ ! $? -eq 0 ]; then
+ echo "ERROR: expecting the string 'msgnum:$i', it's not there"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+done
+
+
+exit_test
diff --git a/tests/imfile-readmode2-polling.sh b/tests/imfile-readmode2-polling.sh
new file mode 100755
index 0000000..2bbe880
--- /dev/null
+++ b/tests/imfile-readmode2-polling.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global( debug.whitelist="on"
+ debug.files=["imfile.c"])
+
+module(load="../plugins/imfile/.libs/imfile" mode="polling" PollingInterval="1")
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" ReadMode="2")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+
+# write the beginning of the file
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input
+
+# sleep a little to give rsyslog a chance to begin processing
+sleep 2
+
+# write some more lines (see https://github.com/rsyslog/rsyslog/issues/144)
+echo 'msgnum:3
+ msgnum:4' >> $RSYSLOG_DYNNAME.input
+echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input # this one shouldn't be written to the output file because of ReadMode 2
+
+# give it time to finish
+sleep 1
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+# give it time to write the output file
+sleep 1
+
+## check if we have the correct number of messages
+
+NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null)
+
+if [ -z $NUMLINES ]; then
+ echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?"
+ exit_test
+ exit 1
+else
+ if [ ! $NUMLINES -eq 3 ]; then
+ echo "ERROR: expecting 3 headers, got $NUMLINES"
+ exit_test
+ exit 1
+ fi
+fi
+
+## check if all the data we expect to get in the file is there
+
+for i in {1..4}; do
+ grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1
+ if [ ! $? -eq 0 ]; then
+ echo "ERROR: expecting the string 'msgnum:$i', it's not there"
+ exit_test
+ exit 1
+ fi
+done
+
+## if we got here, all is good :)
+
+exit_test
diff --git a/tests/imfile-readmode2-vg.sh b/tests/imfile-readmode2-vg.sh
new file mode 100755
index 0000000..20d4002
--- /dev/null
+++ b/tests/imfile-readmode2-vg.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ ReadMode="2")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup_vg
+
+# write the beginning of the file
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input
+wait_file_lines $RSYSLOG_OUT_LOG 1
+
+# write some more lines (see https://github.com/rsyslog/rsyslog/issues/144)
+echo 'msgnum:3
+ msgnum:4' >> $RSYSLOG_DYNNAME.input
+echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input # this one shouldn't be written to the output file because of ReadMode 2
+wait_file_lines $RSYSLOG_OUT_LOG 3
+
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+## check if we have the correct number of messages
+NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null)
+
+if [ -z $NUMLINES ]; then
+ echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+else
+ if [ ! $NUMLINES -eq 3 ]; then
+ echo "ERROR: expecting 3 headers, got $NUMLINES"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+fi
+
+## check if all the data we expect to get in the file is there
+
+for i in {1..4}; do
+ grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1
+ if [ ! $? -eq 0 ]; then
+ echo "ERROR: expecting the string 'msgnum:$i', it's not there"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+done
+
+## if we got here, all is good :)
+
+exit_test
diff --git a/tests/imfile-readmode2-with-persists-data-during-stop.sh b/tests/imfile-readmode2-with-persists-data-during-stop.sh
new file mode 100755
index 0000000..552e181
--- /dev/null
+++ b/tests/imfile-readmode2-with-persists-data-during-stop.sh
@@ -0,0 +1,102 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. $srcdir/diag.sh check-inotify
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ ReadMode="2")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup
+
+# write the beginning of the file
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input
+
+# sleep a little to give rsyslog a chance to begin processing
+sleep 1
+
+# now stop and restart rsyslog so that the file info must be
+# persisted and read again on startup. Results should still be
+# correct ;)
+echo stopping rsyslog
+shutdown_when_empty
+wait_shutdown
+
+# write some more lines - we want to check here if the initial
+# polling loop properly picks up that data. Note that even in
+# inotify case we do have one polling loop at startup, as this
+# is required to find data written while we were stopped.
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+echo 'msgnum:3
+ msgnum:4' >> $RSYSLOG_DYNNAME.input
+
+echo restarting rsyslog
+startup
+echo restarted rsyslog, continuing with test
+
+echo ' msgnum:5' >> $RSYSLOG_DYNNAME.input
+echo 'msgnum:6
+ msgnum:7
+msgnum:8' >> $RSYSLOG_DYNNAME.input
+#msgnum:8 must NOT be written as it is unfinished
+
+# give it time to finish
+sleep 1
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+# give it time to write the output file
+sleep 1
+
+## check if we have the correct number of messages
+
+NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null)
+
+if [ -z $NUMLINES ]; then
+ echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+else
+ if [ ! $NUMLINES -eq 4 ]; then
+ echo "ERROR: expecting 4 headers, got $NUMLINES"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+fi
+
+## check if all the data we expect to get in the file is there
+
+for i in {1..7}; do
+ grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1
+ if [ ! $? -eq 0 ]; then
+ echo "ERROR: expecting the string 'msgnum:$i', it's not there"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+done
+
+## if we got here, all is good :)
+
+exit_test
diff --git a/tests/imfile-readmode2-with-persists.sh b/tests/imfile-readmode2-with-persists.sh
new file mode 100755
index 0000000..71104ba
--- /dev/null
+++ b/tests/imfile-readmode2-with-persists.sh
@@ -0,0 +1,97 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+echo ======================================================================
+echo [imfile-readmode2-with-persists.sh]
+. $srcdir/diag.sh check-inotify
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ Tag="file:"
+ ReadMode="2")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+startup
+
+# write the beginning of the file
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input
+
+# sleep a little to give rsyslog a chance to begin processing
+sleep 1
+
+# now stop and restart rsyslog so that the file info must be
+# persisted and read again on startup. Results should still be
+# correct ;)
+echo stopping rsyslog
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+echo spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+echo restarting rsyslog
+startup
+echo restarted rsyslog, continuing with test
+
+# write some more lines (see https://github.com/rsyslog/rsyslog/issues/144)
+echo 'msgnum:3
+ msgnum:4' >> $RSYSLOG_DYNNAME.input
+echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input # this one shouldn't be written to the output file because of ReadMode 2
+
+# give it time to finish
+sleep 1
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+# give it time to write the output file
+sleep 1
+
+## check if we have the correct number of messages
+
+NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null)
+
+if [ -z $NUMLINES ]; then
+ echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+else
+ if [ ! $NUMLINES -eq 3 ]; then
+ echo "ERROR: expecting 3 headers, got $NUMLINES"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+ fi
+fi
+
+## check if all the data we expect to get in the file is there
+
+for i in {1..4}; do
+ grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1
+ if [ ! $? -eq 0 ]; then
+ echo "ERROR: expecting the string 'msgnum:$i', it's not there"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+ fi
+done
+
+## if we got here, all is good :)
+
+exit_test
diff --git a/tests/imfile-readmode2.sh b/tests/imfile-readmode2.sh
new file mode 100755
index 0000000..c06d269
--- /dev/null
+++ b/tests/imfile-readmode2.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+#export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction stdout"
+#export RSYSLOG_DEBUGLOG="log"
+
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+generate_conf
+add_conf '
+global( debug.whitelist="on"
+ debug.files=["imfile.c"])
+
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" ReadMode="2")
+#input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.*" Tag="file:" ReadMode="2")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+
+# write the beginning of the file
+echo 'msgnum:0
+ msgnum:1' > $RSYSLOG_DYNNAME.input
+echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input
+
+startup
+# sleep a little to give rsyslog a chance to begin processing
+rst_msleep 500
+
+# write some more lines (see https://github.com/rsyslog/rsyslog/issues/144)
+echo 'msgnum:3
+ msgnum:4' >> $RSYSLOG_DYNNAME.input
+echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input # this one shouldn't be written to the output file because of ReadMode 2
+
+# give it time to finish
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+## check if we have the correct number of messages
+NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null)
+if [ -z $NUMLINES ]; then
+ echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+else
+ if [ ! $NUMLINES -eq 3 ]; then
+ echo "ERROR: expecting 3 headers, got $NUMLINES"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+fi
+
+## check if all the data we expect to get in the file is there
+
+for i in {1..4}; do
+ grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1
+ if [ ! $? -eq 0 ]; then
+ echo "ERROR: expecting the string 'msgnum:$i', it's not there"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+done
+
+## if we got here, all is good :)
+
+exit_test
diff --git a/tests/imfile-rename-while-stopped.sh b/tests/imfile-rename-while-stopped.sh
new file mode 100755
index 0000000..9d29b82
--- /dev/null
+++ b/tests/imfile-rename-while-stopped.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under GPLv3
+export TESTMESSAGES=10000
+export RETRIES=10
+export TESTMESSAGESFULL=19999
+echo [imfile-rename.sh]
+. $srcdir/diag.sh check-inotify-only
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+
+/* Filter out busy debug output */
+global(
+ debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+ )
+
+module( load="../plugins/imfile/.libs/imfile"
+ mode="inotify"
+ PollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.*.log"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+input(type="imfile"
+ File="/does/not/exist/*.log"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+
+$template outfmt,"%msg:F,58:2%\n"
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+
+# generate input file first.
+./inputfilegen -m $TESTMESSAGES > $RSYSLOG_DYNNAME.input.1.log
+ls -li $RSYSLOG_DYNNAME.input*
+
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+# Move to another filename
+mv $RSYSLOG_DYNNAME.input.1.log rsyslog.input.2.log
+
+# generate some more input into moved file
+./inputfilegen -m $TESTMESSAGES -i $TESTMESSAGES >> $RSYSLOG_DYNNAME.input.2.log
+ls -li $RSYSLOG_DYNNAME.input*
+echo ls ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+seq_check 0 $TESTMESSAGESFULL
+wc $RSYSLOG_OUT_LOG
+exit_test
diff --git a/tests/imfile-rename.sh b/tests/imfile-rename.sh
new file mode 100755
index 0000000..6d249d3
--- /dev/null
+++ b/tests/imfile-rename.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under GPLv3
+. $srcdir/diag.sh check-inotify-only
+. ${srcdir:=.}/diag.sh init
+export TESTMESSAGES=10000
+export RETRIES=50
+export TESTMESSAGESFULL=19999
+
+generate_conf
+add_conf '
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+
+/* Filter out busy debug output */
+global(
+ debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+ )
+
+module( load="../plugins/imfile/.libs/imfile"
+ mode="inotify"
+ PollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.*.log"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+input(type="imfile"
+ File="/does/not/exist/*.log"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+
+$template outfmt,"%msg:F,58:2%\n"
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+if $msg contains "imfile:" then
+ action(
+ type="omfile"
+ file="'$RSYSLOG_DYNNAME.errmsgs'"
+ )
+'
+
+# generate input file first.
+./inputfilegen -m $TESTMESSAGES > $RSYSLOG_DYNNAME.input.1.log
+ls -l $RSYSLOG_DYNNAME.input*
+
+startup
+
+# sleep a little to give rsyslog a chance to begin processing
+
+wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGES $RETRIES
+
+# Move to another filename
+mv $RSYSLOG_DYNNAME.input.1.log rsyslog.input.2.log
+
+./msleep 500
+
+# Write into the renamed file
+echo 'testmessage1
+testmessage2' >> rsyslog.input.2.log
+
+./msleep 500
+
+if grep "imfile: internal error? inotify provided watch descriptor" < "$RSYSLOG_DYNNAME.errmsgs" ; then
+ echo "Error: inotify event from renamed file"
+ exit 1
+fi
+
+# generate some more input into moved file
+./inputfilegen -m $TESTMESSAGES -i $TESTMESSAGES >> $RSYSLOG_DYNNAME.input.2.log
+ls -l $RSYSLOG_DYNNAME.input*
+echo ls ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+./msleep 500
+
+let msgcount="2* $TESTMESSAGES"
+wait_file_lines $RSYSLOG_OUT_LOG $msgcount $RETRIES
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+seq_check 0 $TESTMESSAGESFULL
+exit_test
diff --git a/tests/imfile-statefile-delete.sh b/tests/imfile-statefile-delete.sh
new file mode 100755
index 0000000..cbe4128
--- /dev/null
+++ b/tests/imfile-statefile-delete.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# added 2019-02-28
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export TESTMESSAGES=1000
+export TESTMESSAGESFULL=999
+export RETRIES=50
+
+# Uncomment fdor debuglogs
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog"
+
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+module(load="../plugins/imfile/.libs/imfile" mode="inotify" PollingInterval="1")
+input(type="imfile" tag="file:" file="./'$RSYSLOG_DYNNAME'.input")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+./inputfilegen -m $TESTMESSAGES > $RSYSLOG_DYNNAME.input
+inode=$(get_inode "$RSYSLOG_DYNNAME.input")
+startup
+wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGES $RETRIES
+rm $RSYSLOG_DYNNAME.input
+sleep_time_ms=0
+while ls $RSYSLOG_DYNNAME.spool/imfile-state:$inode:* 1> /dev/null 2>&1; do
+ ./msleep 100
+ ((sleep_time_ms+=100))
+ if [ $sleep_time_ms -ge 6000 ]; then
+ touch $RSYSLOG_DYNNAME:.tmp
+ fi
+ if [ $sleep_time_ms -ge 30000 ]; then
+ printf 'FAIL: state file still exists when it should have been deleted\nspool dir is:\n'
+ ls -l $RSYSLOG_DYNNAME.spool
+ error_exit 1
+ fi
+done
+shutdown_when_empty
+wait_shutdown
+seq_check 0 $TESTMESSAGESFULL # check we got the message correctly
+exit_test
diff --git a/tests/imfile-statefile-directory.sh b/tests/imfile-statefile-directory.sh
new file mode 100755
index 0000000..2c14958
--- /dev/null
+++ b/tests/imfile-statefile-directory.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# added 2019-04-25 by rgerhards
+# check that the "statfile.directory" module parameter is accepted
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+mkdir $RSYSLOG_DYNNAME.statefiles
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile"
+ statefile.directory="'${RSYSLOG_DYNNAME}'.statefiles")
+input(type="imfile" tag="file:" file="./'$RSYSLOG_DYNNAME'.input")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+# generate a very small file so that imfile cannot generate file_id (simple case)
+./inputfilegen -m1 > $RSYSLOG_DYNNAME.input
+startup
+shutdown_when_empty
+wait_shutdown
+seq_check 0 0 # check we got the messages correctly
+# and also check state file name is correct:
+# shellcheck disable=SC2012 - we do not display (or even use) the file name
+inode=$(ls -i "$RSYSLOG_DYNNAME.input"|awk '{print $1}')
+if [ ! -f "$RSYSLOG_DYNNAME.statefiles/imfile-state:$inode" ]; then
+ printf 'FAIL: state file name incorrect,\nexpected \"%s\"\nstatefiles dir is:\n' \
+ $RSYSLOG_DYNNAME.statefiles/imfile-state:$inode
+ ls -l $RSYSLOG_DYNNAME.statefiles
+ error_exit 1
+fi
+exit_test
diff --git a/tests/imfile-statefile-no-delete.sh b/tests/imfile-statefile-no-delete.sh
new file mode 100755
index 0000000..309b5d4
--- /dev/null
+++ b/tests/imfile-statefile-no-delete.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# Added 2019-02-28
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export TESTMESSAGES=1000
+export TESTMESSAGESFULL=999
+export RETRIES=50
+
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+module(load="../plugins/imfile/.libs/imfile" mode="inotify" PollingInterval="1")
+input(type="imfile" tag="file:" file="./'$RSYSLOG_DYNNAME'.input" deleteStateOnFileDelete="off")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+./inputfilegen -m $TESTMESSAGES > $RSYSLOG_DYNNAME.input
+inode=$(get_inode "$RSYSLOG_DYNNAME.input")
+startup
+wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGES $RETRIES
+rm $RSYSLOG_DYNNAME.input
+# sleep a little to give rsyslog a chance to notice the deleted file
+./msleep 2000
+
+shutdown_when_empty
+wait_shutdown
+seq_check 0 $TESTMESSAGESFULL # check we got the message correctly
+if ! ls $RSYSLOG_DYNNAME.spool/imfile-state:$inode:* 1> /dev/null 2>&1; then
+ printf 'FAIL: state file was deleted when it should not have been\nspool dir is:\n'
+ ls -l $RSYSLOG_DYNNAME.spool
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imfile-statefile-no-file_id-TO-file_id.sh b/tests/imfile-statefile-no-file_id-TO-file_id.sh
new file mode 100755
index 0000000..d2b7722
--- /dev/null
+++ b/tests/imfile-statefile-no-file_id-TO-file_id.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# added 2019-02-28 by rgerhards
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile" tag="file:" file="./'$RSYSLOG_DYNNAME'.input")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+# generate a very small file so that imfile cannot generate file_id
+./inputfilegen -m1 > $RSYSLOG_DYNNAME.input
+startup
+shutdown_when_empty
+wait_shutdown
+seq_check 0 0 # check we got the (one) message correctly
+# and also check state file name is correct:
+inode=$(get_inode "$RSYSLOG_DYNNAME.input")
+if [ ! -f "$RSYSLOG_DYNNAME.spool/imfile-state:$inode" ]; then
+ printf 'FAIL: state file name incorrect,\nexpected \"%s\"\nspool dir is:\n' \
+ $RSYSLOG_DYNNAME.spool/imfile-state:$inode
+ ls -l $RSYSLOG_DYNNAME.spool
+ error_exit 1
+fi
+
+printf '\nSTAGE 1 OK - inode-only state file properly generated\n\n'
+
+# now add data to the input file, up to a point where we have file_id.
+# rsyslog must update state file name AND remove inode-only one.
+./inputfilegen -m999 -i1 >> $RSYSLOG_DYNNAME.input
+startup
+wait_file_lines "$RSYSLOG_OUT_LOG" 1000
+shutdown_when_empty
+wait_shutdown
+
+seq_check 0 999 # check we got the messages correctly
+# and verify the state files are correct
+if [ -f "$RSYSLOG_DYNNAME.spool/imfile-state:$inode" ]; then
+ printf 'FAIL: inode-only state file still exists, but must not.\nincorrect name: \"%s\"\nspool dir is:\n' \
+ $RSYSLOG_DYNNAME.spool/imfile-state:$inode
+ ls -l $RSYSLOG_DYNNAME.spool
+ error_exit 1
+fi
+ ls -l $RSYSLOG_DYNNAME.spool
+exit_test
diff --git a/tests/imfile-statefile-no-file_id.sh b/tests/imfile-statefile-no-file_id.sh
new file mode 100755
index 0000000..d230c91
--- /dev/null
+++ b/tests/imfile-statefile-no-file_id.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# added 2019-02-28 by rgerhards
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile" tag="file:" file="./'$RSYSLOG_DYNNAME'.input")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+# generate a very small file so that imfile cannot generate file_id
+./inputfilegen -m1 > $RSYSLOG_DYNNAME.input
+startup
+shutdown_when_empty
+wait_shutdown
+seq_check 0 0 # check we got the messages correctly
+# and also check state file name is correct:
+inode=$(get_inode "$RSYSLOG_DYNNAME.input")
+
+printf '\nSTAGE 1 OK - inode-only state file properly generated\n\n'
+
+# now add small amount of data, so that file_id can still not be
+# generated. Check that state file remains valid.
+# rsyslog must update state file name AND remove inode-only one.
+./inputfilegen -m3 -i1 >> $RSYSLOG_DYNNAME.input
+startup
+wait_file_lines "$RSYSLOG_OUT_LOG" 4
+shutdown_when_empty
+wait_shutdown
+
+seq_check 0 3 # check we got the messages correctly
+# and verify the state files are correct
+if [ ! -f "$RSYSLOG_DYNNAME.spool/imfile-state:$inode" ]; then
+ printf 'FAIL: STAGE 2 state file name incorrect,\nexpected \"%s\"\nspool dir is:\n' \
+ $RSYSLOG_DYNNAME.spool/imfile-state:$inode
+ ls -l $RSYSLOG_DYNNAME.spool
+ error_exit 1
+fi
+printf '\nSTAGE 2 OK - inode-only state file properly maintained\n\n'
+
+exit_test
diff --git a/tests/imfile-symlink-ext-tmp-dir-tree.sh b/tests/imfile-symlink-ext-tmp-dir-tree.sh
new file mode 100755
index 0000000..df15f54
--- /dev/null
+++ b/tests/imfile-symlink-ext-tmp-dir-tree.sh
@@ -0,0 +1,80 @@
+#!/bin/bash
+# This test creates multiple symlinks (all watched by rsyslog via wildcard)
+# chained to target files via additional symlinks and checks that all files
+# are recorded with correct corresponding metadata (name of symlink
+# matching configuration).
+# This is part of the rsyslog testbench, released under ASL 2.0
+. "${srcdir:=.}"/diag.sh init
+. "$srcdir"/diag.sh check-inotify
+
+# #define FILE_DELETE_DELAY 5 /* how many seconds to wait before finally deleting a gone file */
+export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+export RSYSLOG_DEBUGLOG="log"
+export TEST_TIMEOUT=30
+
+# generate input files first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+generate_conf
+add_conf '
+# comment out if you need more debug info:
+global( debug.whitelist="on" debug.files=["imfile.c"]
+ workDirectory="./'"$RSYSLOG_DYNNAME"'.work"
+)
+module(load="../plugins/imfile/.libs/imfile" mode="inotify")
+input(type="imfile" File="./'"$RSYSLOG_DYNNAME"'.links/*.log" Tag="file:"
+ Severity="error" Facility="local7" addMetadata="on")
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value=", filename: ")
+ property(name="$!metadata!filename")
+ constant(value=", fileoffset: ")
+ property(name="$!metadata!fileoffset")
+ constant(value="\n")
+}
+if $msg contains "msgnum:" then
+ action( type="omfile" file="'"$RSYSLOG_DYNNAME.out/$RSYSLOG_OUT_LOG"'" template="outfmt")
+'
+
+mkdir "$RSYSLOG_DYNNAME".links "$RSYSLOG_DYNNAME".work "$RSYSLOG_DYNNAME".out
+
+printf '\ncreating %s\n' "$RSYSLOG_DYNNAME".targets/container-1/logs/0.log
+mkdir -p "$RSYSLOG_DYNNAME".targets/container-1/logs
+./inputfilegen -m 1 >"$RSYSLOG_DYNNAME".targets/container-1/logs/0.log
+ls -l "$RSYSLOG_DYNNAME".targets/container-1/logs/0.log
+ln -sv "$PWD/$RSYSLOG_DYNNAME".targets/container-1/logs/0.log "$PWD/$RSYSLOG_DYNNAME".links/container-1.log
+printf '%s generated link %s\n' "$(tb_timestamp)" "container-1"
+ls -l "$RSYSLOG_DYNNAME".links/container-1.log
+
+# Start rsyslog now
+startup
+
+PID=$(cat "$RSYSLOG_PIDBASE".pid)
+echo "Rsyslog pid $RSYSLOG_PIDBASE.pid=$PID"
+if [[ "$PID" == "" ]]; then
+ error_exit 1
+fi
+
+echo "INFO: check files"
+# wait until this files has been opened
+check_fd_for_pid "$PID" exists "container-1/logs/0.log"
+check_fd_for_pid "$PID" exists "container-1/logs"
+
+echo "INFO: remove watched files"
+rm -vr "$RSYSLOG_DYNNAME".targets/container-1
+rm -v "$RSYSLOG_DYNNAME".links/container-1.log
+
+until check_fd_for_pid "$PID" absent "container-1/logs (deleted)"; do
+ if ((_wait_for_absent++ > TEST_TIMEOUT)); then
+ error_exit 1
+ fi
+ echo "INFO: trigger fd unlinking"
+ ./inputfilegen -m 1 >"$RSYSLOG_DYNNAME".links/gogogo.log
+ ./msleep 1000
+ rm -v "$RSYSLOG_DYNNAME".links/gogogo.log
+ ./msleep 10
+done
+
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/imfile-symlink-multi.sh b/tests/imfile-symlink-multi.sh
new file mode 100755
index 0000000..7e7c8f0
--- /dev/null
+++ b/tests/imfile-symlink-multi.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# This test points multiple symlinks (all watched by rsyslog via wildcard)
+# to single file and checks that message is reported once for each symlink
+# with correct corresponding metadata.
+# This is part of the rsyslog testbench, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+export IMFILEINPUTFILES="10"
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+# comment out if you need more debug info:
+ global( debug.whitelist="on"
+ debug.files=["imfile.c"])
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+module(load="../plugins/imfile/.libs/imfile"
+ mode="inotify" normalizePath="off")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input-symlink.log" Tag="file:"
+ Severity="error" Facility="local7" addMetadata="on")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.*.log" Tag="file:"
+ Severity="error" Facility="local7" addMetadata="on")
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value=", filename: ")
+ property(name="$!metadata!filename")
+ constant(value=", fileoffset: ")
+ property(name="$!metadata!fileoffset")
+ constant(value="\n")
+}
+if $msg contains "msgnum:" then
+ action( type="omfile" file="'${RSYSLOG_OUT_LOG}'" template="outfmt")
+'
+# generate input files first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+
+imfilebefore="$RSYSLOG_DYNNAME.input-symlink.log"
+./inputfilegen -m 1 > $imfilebefore
+mkdir $RSYSLOG_DYNNAME.targets
+# Start rsyslog now before adding more files
+startup
+
+cp $imfilebefore $RSYSLOG_DYNNAME.targets/target.log
+for i in `seq 2 $IMFILEINPUTFILES`;
+do
+ ln -s $RSYSLOG_DYNNAME.targets/target.log $RSYSLOG_DYNNAME.input.$i.log
+ # Wait little for correct timing
+ ./msleep 50
+done
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+sort ${RSYSLOG_OUT_LOG} > ${RSYSLOG_OUT_LOG}.sorted
+
+echo HEADER msgnum:00000000:, filename: ./$RSYSLOG_DYNNAME.input-symlink.log, fileoffset: 0 > $RSYSLOG_DYNNAME.expected
+for i in `seq 2 $IMFILEINPUTFILES` ; do
+ echo HEADER msgnum:00000000:, filename: ./$RSYSLOG_DYNNAME.input.${i}.log, fileoffset: 0 >> $RSYSLOG_DYNNAME.expected
+done
+sort < $RSYSLOG_DYNNAME.expected | cmp - ${RSYSLOG_OUT_LOG}.sorted
+if [ ! $? -eq 0 ]; then
+ echo "invalid output generated, ${RSYSLOG_OUT_LOG} is:"
+ cat -n $RSYSLOG_OUT_LOG
+ echo EXPECTED:
+ cat -n $RSYSLOG_DYNNAME.expected
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imfile-symlink.sh b/tests/imfile-symlink.sh
new file mode 100755
index 0000000..65b1a61
--- /dev/null
+++ b/tests/imfile-symlink.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+# This test creates multiple symlinks (all watched by rsyslog via wildcard)
+# chained to target files via additional symlinks and checks that all files
+# are recorded with correct corresponding metadata (name of symlink
+# matching configuration).
+# This is part of the rsyslog testbench, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+export IMFILEINPUTFILES="10"
+export IMFILELASTINPUTLINES="3"
+export IMFILECHECKTIMEOUT="60"
+
+# generate input files first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+mkdir $RSYSLOG_DYNNAME.statefiles
+generate_conf
+add_conf '
+# comment out if you need more debug info:
+ global( debug.whitelist="on"
+ debug.files=["imfile.c"])
+module(load="../plugins/imfile/.libs/imfile"
+ statefile.directory="'${RSYSLOG_DYNNAME}'.statefiles"
+ mode="inotify" normalizePath="off")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input-symlink.log" Tag="file:"
+ Severity="error" Facility="local7" addMetadata="on")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.*.log" Tag="file:"
+ Severity="error" Facility="local7" addMetadata="on")
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value=", filename: ")
+ property(name="$!metadata!filename")
+ constant(value=", fileoffset: ")
+ property(name="$!metadata!fileoffset")
+ constant(value="\n")
+}
+if $msg contains "msgnum:" then
+ action( type="omfile" file="'${RSYSLOG_OUT_LOG}'" template="outfmt")
+'
+
+./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input-symlink.log
+mkdir $RSYSLOG_DYNNAME.targets
+
+# Start rsyslog now before adding more files
+startup
+
+for i in $(seq 2 $IMFILEINPUTFILES);
+do
+ printf '\ncreating %s\n' $RSYSLOG_DYNNAME.targets/$i.log
+ ./inputfilegen -m 1 -i $((i-1)) > $RSYSLOG_DYNNAME.targets/$i.log
+ ls -l $RSYSLOG_DYNNAME.targets/$i.log
+ ln -sv $RSYSLOG_DYNNAME.targets/$i.log $RSYSLOG_DYNNAME.link.$i.log
+ ln -sv $RSYSLOG_DYNNAME.link.$i.log $RSYSLOG_DYNNAME.input.$i.log
+ printf '%s generated file %s\n' "$(tb_timestamp)" "$i"
+ ls -l $RSYSLOG_DYNNAME.link.$i.log
+ # wait until this file has been processed
+ content_check_with_count "HEADER msgnum:000000" $i $IMFILECHECKTIMEOUT
+done
+
+./inputfilegen -m $IMFILELASTINPUTLINES > $RSYSLOG_DYNNAME.input.$((IMFILEINPUTFILES + 1)).log
+ls -l $RSYSLOG_DYNNAME.input.* $RSYSLOG_DYNNAME.link.* $RSYSLOG_DYNNAME.targets
+
+# Content check with timeout
+content_check_with_count "input.11.log" $IMFILELASTINPUTLINES $IMFILECHECKTIMEOUT
+
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/imfile-truncate-2GB-file.sh b/tests/imfile-truncate-2GB-file.sh
new file mode 100755
index 0000000..67c9ac1
--- /dev/null
+++ b/tests/imfile-truncate-2GB-file.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# written 2018-11-09 by Rainer Gerhards
+# this test checks that 2GiB (31 bit) file size region is handled correctly
+# it first generates a file that is 2GiB-64 bytes, processes it, and then
+# adds a couple of messages to get it over 2GiB.
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export TB_TEST_MAX_RUNTIME=3600 # test is very slow as it works on large files
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" reopenOnTruncate="on")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+touch $RSYSLOG_DYNNAME.input
+startup
+
+# initial file: 2GiB - 1 message (54 byte)
+./inputfilegen -s 2147483584 -d47 -M $RSYSLOG_DYNNAME.msgcnt > $RSYSLOG_DYNNAME.input
+ls -lh $RSYSLOG_DYNNAME.input
+export NUMMESSAGES="$(cat $RSYSLOG_DYNNAME.msgcnt)"
+
+wait_file_lines --delay 2500 --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES 3000
+
+# add one message --> exactly 2GB
+./inputfilegen -m1 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input
+ls -lh $RSYSLOG_DYNNAME.input
+(( NUMMESSAGES++ ))
+wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES
+
+# add one more message --> now we go over 2GB
+./inputfilegen -m1 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input
+ls -lh $RSYSLOG_DYNNAME.input
+(( NUMMESSAGES++ ))
+wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES
+
+# add even more messages
+./inputfilegen -m10000 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input
+ls -lh $RSYSLOG_DYNNAME.input
+NUMMESSAGES=$(( NUMMESSAGES + 10000 ))
+wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES
+
+shutdown_when_empty
+wait_shutdown
+seq_check 0 $(( NUMMESSAGES - 1))
+exit_test
diff --git a/tests/imfile-truncate-line.sh b/tests/imfile-truncate-line.sh
new file mode 100755
index 0000000..214e0c1
--- /dev/null
+++ b/tests/imfile-truncate-line.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+# This test mimics the test imfile-readmode2.sh, but works via
+# endmsg.regex. It's kind of a base test for the regex functionality.
+echo ======================================================================
+# Check if inotify header exist
+echo [imfile-truncate-line.sh]
+. $srcdir/diag.sh check-inotify
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 128
+global(oversizemsg.input.mode="accept" oversizemsg.report="on")
+module(load="../plugins/imfile/.libs/imfile")
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input"
+ discardTruncatedMsg="off"
+ Tag="file:"
+ startmsg.regex="^[^ ]"
+ ruleset="ruleset")
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="\n")
+}
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt")
+'
+startup
+
+# write the beginning of the file
+echo 'msgnum:0
+msgnum:1
+msgnum:2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ msgnum:3 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ msgnum:4 cccccccccccccccccccccccccccccccccccccccccccc
+ msgnum:5 dddddddddddddddddddddddddddddddddddddddddddd
+msgnum:6 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+ msgnum:7 ffffffffffffffffffffffffffffffffffffffffffff
+ msgnum:8 gggggggggggggggggggggggggggggggggggggggggggg
+msgnum:9' > $RSYSLOG_DYNNAME.input
+# the next line terminates our test. It is NOT written to the output file,
+# as imfile waits whether or not there is a follow-up line that it needs
+# to combine.
+echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input
+# sleep a little to give rsyslog a chance to begin processing
+./msleep 500
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+printf 'HEADER msgnum:0
+HEADER msgnum:1
+HEADER msgnum:2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\\n msgnum:3 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\\\\n msgnum:4 ccccccc
+HEADER ccccccccccccccccccccccccccccccccccccc\\\\n msgnum:5 dddddddddddddddddddddddddddddddddddddddddddd
+HEADER msgnum:6 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\\\\n msgnum:7 ffffffffffffffffffffffffffffffffffffffffffff\\\\n msgnum:8 ggggggg
+HEADER ggggggggggggggggggggggggggggggggggggg
+HEADER msgnum:9\n' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid multiline message generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+grep "imfile error:.*message will be split and processed" ${RSYSLOG2_OUT_LOG} > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message from missing input file not found. ${RSYSLOG2_OUT_LOG} is:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imfile-truncate-multiple.sh b/tests/imfile-truncate-multiple.sh
new file mode 100755
index 0000000..73d691a
--- /dev/null
+++ b/tests/imfile-truncate-multiple.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# this test checks truncation mode, and does so with multiple truncations of
+# the input file.
+# It also needs a larger load, which shall be sufficient to do begin of file
+# checks as well as should support file id hash generation.
+# addd 2016-10-06 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile" pollingInterval="1")
+
+input(type="imfile" File="'./$RSYSLOG_DYNNAME'.input" Tag="file:" reopenOnTruncate="on")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+
+# write the beginning of the file
+NUMMSG=1000
+./inputfilegen -m 1000 -i0 > $RSYSLOG_DYNNAME.input
+ls -li $RSYSLOG_DYNNAME.input
+inode=$(get_inode $RSYSLOG_DYNNAME.input )
+echo inode $inode
+
+startup
+
+for i in {0..50}; do
+ # check that previous msg injection worked
+ wait_file_lines $RSYSLOG_OUT_LOG $NUMMSG 100
+ seq_check 0 $((NUMMSG - 1))
+
+ # begin new inject cycle
+ generate_msgs=$(( i * 50))
+ echo generating $NUMMSG .. $((NUMMSG + generate_msgs -1))
+ ./inputfilegen -m$generate_msgs -i$NUMMSG > $RSYSLOG_DYNNAME.input
+ (( NUMMSG=NUMMSG+generate_msgs ))
+ if [ $inode -ne $( get_inode $RSYSLOG_DYNNAME.input ) ]; then
+ echo FAIL testbench did not keep same inode number, expected $inode
+ ls -li $RSYSLOG_DYNNAME.input
+ exit 100
+ fi
+done
+
+echo generated $NUMMSG messages
+
+shutdown_when_empty
+wait_shutdown
+
+seq_check 0 $((NUMMSG - 1))
+exit_test
diff --git a/tests/imfile-truncate.sh b/tests/imfile-truncate.sh
new file mode 100755
index 0000000..72ef168
--- /dev/null
+++ b/tests/imfile-truncate.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# addd 2016-10-06 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" reopenOnTruncate="on")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then {
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+} else {
+ action( type="omfile" file="'$RSYSLOG_DYNNAME'.rsyslog")
+}
+'
+
+# write the beginning of the file
+echo 'msgnum:0
+msgnum:1' > $RSYSLOG_DYNNAME.input
+
+startup
+
+wait_queueempty # wait for message to be processed
+
+# truncate and write some more lines (see https://github.com/rsyslog/rsyslog/issues/1090)
+echo 'msgnum:2' > $RSYSLOG_DYNNAME.input
+wait_queueempty # wait for message to be processed
+
+echo 'msgnum:3
+msgnum:4' >> $RSYSLOG_DYNNAME.input
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+printf 'Messages from rsyslog itself:\n'
+cat -n $RSYSLOG_DYNNAME.rsyslog
+
+seq_check 0 4
+exit_test
diff --git a/tests/imfile-wildcards-dirs-multi.sh b/tests/imfile-wildcards-dirs-multi.sh
new file mode 100755
index 0000000..3155dc0
--- /dev/null
+++ b/tests/imfile-wildcards-dirs-multi.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under GPLv3
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify-only
+export IMFILEINPUTFILES="10"
+export IMFILEINPUTFILESSTEPS="5"
+#export IMFILEINPUTFILESALL=$(($IMFILEINPUTFILES * $IMFILEINPUTFILESSTEPS))
+export IMFILECHECKTIMEOUT="60"
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+
+/* Filter out busy debug output, comment out if needed */
+/*
+global(
+ debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+)
+*/
+
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+
+module( load="../plugins/imfile/.libs/imfile"
+ mode="inotify"
+ PollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.*/*/*.logfile"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value=", ")
+ property(name="$!metadata!filename")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+# generate input files first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+
+# Start rsyslog now before adding more files
+startup
+
+for j in $(seq 1 $IMFILEINPUTFILESSTEPS);
+do
+ echo "Loop Num $j"
+
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ mkdir $RSYSLOG_DYNNAME.input.dir$i
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$i
+ touch $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile
+ ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile
+ done
+
+ ls -d $RSYSLOG_DYNNAME.input.*
+
+ # Check correct amount of input files each time
+ IMFILEINPUTFILESALL=$((IMFILEINPUTFILES * j))
+ content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILESALL $IMFILECHECKTIMEOUT
+
+ # Delete all but first!
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$i/
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i
+ done
+
+ # Helps in testbench parallel mode.
+ # Otherwise sometimes directories are not marked deleted in imfile before they get created again.
+ # This is properly a real issue in imfile when FILE IO is high.
+ ./msleep 1000
+done
+
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/imfile-wildcards-dirs-multi2.sh b/tests/imfile-wildcards-dirs-multi2.sh
new file mode 100755
index 0000000..5199301
--- /dev/null
+++ b/tests/imfile-wildcards-dirs-multi2.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under GPLv3
+. ${srcdir:=.}/diag.sh init
+export IMFILEINPUTFILES="1"
+export IMFILEINPUTFILESSTEPS="5"
+#export IMFILEINPUTFILESALL=$(($IMFILEINPUTFILES * $IMFILEINPUTFILESSTEPS))
+export IMFILECHECKTIMEOUT="60"
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+/* Filter out busy debug output, comment out if needed */
+global(
+ debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+)
+
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+
+module( load="../plugins/imfile/.libs/imfile"
+ mode="inotify"
+ PollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.dir1/*/testdir/file.logfile"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value=", ")
+ property(name="$!metadata!filename")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+# generate input files first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+
+for i in $(seq 1 $IMFILEINPUTFILES);
+do
+ echo "Make $RSYSLOG_DYNNAME.input.dir$i"
+ mkdir $RSYSLOG_DYNNAME.input.dir$i
+done
+
+# Start rsyslog now before adding more files
+startup
+
+for j in $(seq 1 $IMFILEINPUTFILESSTEPS);
+do
+ echo "Loop Num $j"
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ echo "Make $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir"
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir
+ touch $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/file.logfile
+ ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/file.logfile
+ done
+ ls -d $RSYSLOG_DYNNAME.input.*
+
+ # Check correct amount of input files each time
+ IMFILEINPUTFILESALL=$((IMFILEINPUTFILES * j))
+ content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILESALL $IMFILECHECKTIMEOUT
+
+ # Delete all but first!
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/file.logfile
+ rm -rr $RSYSLOG_DYNNAME.input.dir$i/dir$j
+ done
+
+ # Helps in testbench parallel mode.
+ # Otherwise sometimes directories are not marked deleted in imfile before they get created again.
+ # This is properly a real issue in imfile when FILE IO is high.
+ ./msleep 1000
+done
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+exit_test
diff --git a/tests/imfile-wildcards-dirs-multi3.sh b/tests/imfile-wildcards-dirs-multi3.sh
new file mode 100755
index 0000000..1f851bb
--- /dev/null
+++ b/tests/imfile-wildcards-dirs-multi3.sh
@@ -0,0 +1,96 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under GPLv3
+. ${srcdir:=.}/diag.sh init
+export IMFILEINPUTFILES="1"
+export IMFILEINPUTFILESSTEPS="5"
+#export IMFILEINPUTFILESALL=$(($IMFILEINPUTFILES * $IMFILEINPUTFILESSTEPS))
+export IMFILECHECKTIMEOUT="60"
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+/* Filter out busy debug output, comment out if needed */
+global(
+ debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+)
+
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+
+module( load="../plugins/imfile/.libs/imfile"
+ mode="inotify"
+ PollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.*/*/testdir/*/file.logfile"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value=", ")
+ property(name="$!metadata!filename")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+# generate input files first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+
+for i in $(seq 1 $IMFILEINPUTFILES);
+do
+ echo "Make $RSYSLOG_DYNNAME.input.dir$i"
+ mkdir $RSYSLOG_DYNNAME.input.dir$i
+ echo created!
+done
+
+# Start rsyslog now before adding more files
+startup
+# sleep a little to give rsyslog a chance to begin processing
+sleep 2
+
+for j in $(seq 1 $IMFILEINPUTFILESSTEPS);
+do
+ echo "Loop Num $j"
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ echo "Make $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir"
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/subdir$j
+ touch $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/subdir$j/file.logfile
+ ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/subdir$j/file.logfile
+ ls -l $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/subdir$j/file.logfile
+ done
+ ls -d $RSYSLOG_DYNNAME.input.*
+
+ # Check correct amount of input files each time
+ IMFILEINPUTFILESALL=$((IMFILEINPUTFILES * j))
+ content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILESALL $IMFILECHECKTIMEOUT
+
+ # Delete all but first!
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/subdir$j/file.logfile
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$j
+ done
+
+ # Helps in testbench parallel mode.
+ # Otherwise sometimes directories are not marked deleted in imfile before they get created again.
+ # This is properly a real issue in imfile when FILE IO is high.
+ ./msleep 1000
+done
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+exit_test
diff --git a/tests/imfile-wildcards-dirs-multi4.sh b/tests/imfile-wildcards-dirs-multi4.sh
new file mode 100755
index 0000000..367d75d
--- /dev/null
+++ b/tests/imfile-wildcards-dirs-multi4.sh
@@ -0,0 +1,95 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under GPLv3
+. ${srcdir:=.}/diag.sh init
+export IMFILEINPUTFILES="1"
+export IMFILEINPUTFILESSTEPS="5"
+#export IMFILEINPUTFILESALL=$((IMFILEINPUTFILES * IMFILEINPUTFILESSTEPS))
+export IMFILECHECKTIMEOUT="60"
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+/* Filter out busy debug output, comment out if needed */
+global(
+ debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+)
+
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+
+module( load="../plugins/imfile/.libs/imfile"
+ mode="inotify"
+ PollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.dir1/*/*/*/*/*/file.logfile"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value=", ")
+ property(name="$!metadata!filename")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+. $srcdir/diag.sh check-inotify
+# generate input files first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+
+# Start rsyslog now before adding more files
+startup
+
+for i in $(seq 1 $IMFILEINPUTFILES);
+do
+ echo "Make $RSYSLOG_DYNNAME.input.dir$i"
+ mkdir $RSYSLOG_DYNNAME.input.dir$i
+done
+
+for j in $(seq 1 $IMFILEINPUTFILESSTEPS);
+do
+ echo "Loop Num $j"
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ echo "Make $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir"
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/su$j
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/su$j/bd$j
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/su$j/bd$j/ir$j
+ touch $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/su$j/bd$j/ir$j/file.logfile
+ ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/su$j/bd$j/ir$j/file.logfile
+ done
+ ls -d $RSYSLOG_DYNNAME.input.*
+
+ # Check correct amount of input files each time
+ IMFILEINPUTFILESALL=$((IMFILEINPUTFILES * j))
+ content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILESALL $IMFILECHECKTIMEOUT
+
+ # Delete all but first!
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/su$j/bd$j/ir$j/file.logfile
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$j
+ done
+
+ # Helps in testbench parallel mode.
+ # Otherwise sometimes directories are not marked deleted in imfile before they get created again.
+ # This is properly a real issue in imfile when FILE IO is high.
+ ./msleep 1000
+done
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+exit_test
diff --git a/tests/imfile-wildcards-dirs-multi5-polling.sh b/tests/imfile-wildcards-dirs-multi5-polling.sh
new file mode 100755
index 0000000..db7710b
--- /dev/null
+++ b/tests/imfile-wildcards-dirs-multi5-polling.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export IMFILEINPUTFILES="8"
+export IMFILEINPUTFILESSTEPS="5"
+export IMFILECHECKTIMEOUT="15"
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global( debug.whitelist="on"
+ debug.files=["imfile.c", "stream.c"])
+# debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q",
+# "msg.c", "../action.c", "imdiag.c"])
+
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+
+module(load="../plugins/imfile/.libs/imfile" mode="polling" pollingInterval="1")
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.dir?/*/*.logfile"
+ Tag="file:" Severity="error" Facility="local7" addMetadata="on")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.alt/alt*file"
+ Tag="file:" Severity="error" Facility="local7" addMetadata="on")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value=", ")
+ property(name="$!metadata!filename")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+
+# create first directory and file before startup, so ensure we will NOT
+# get an initial inotify notify for it!
+#mkdir $RSYSLOG_DYNNAME.input.alt
+#./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.alt/altfile.logfile
+#mkdir $RSYSLOG_DYNNAME.input.dir1
+# the following is INVALID, as this is a file, but must be a directory!
+#./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir0
+
+startup
+
+for j in $(seq 1 $IMFILEINPUTFILESSTEPS); do
+ cp log log.$j
+ echo "Loop Num $j"
+
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ mkdir $RSYSLOG_DYNNAME.input.dir$i
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$i
+ # proposed by AL - why? touch $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile
+ ./inputfilegen -i $j -m 1 > $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile
+ done
+
+ ls -d $RSYSLOG_DYNNAME.input.*
+
+ # Check correct amount of input files each time
+ IMFILEINPUTFILESALL=$((IMFILEINPUTFILES * j))
+ content_check_with_count "HEADER msgnum:000000" $IMFILEINPUTFILESALL $IMFILECHECKTIMEOUT
+ # Delete all but first!
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i
+ done
+done
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+exit_test
diff --git a/tests/imfile-wildcards-dirs-multi5.sh b/tests/imfile-wildcards-dirs-multi5.sh
new file mode 100755
index 0000000..f6026f3
--- /dev/null
+++ b/tests/imfile-wildcards-dirs-multi5.sh
@@ -0,0 +1,87 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under GPLv3
+. ${srcdir:=.}/diag.sh init
+export IMFILEINPUTFILES="8" #"8"
+export IMFILEINPUTFILESSTEPS="5" #"5"
+#export IMFILEINPUTFILESALL=$(($IMFILEINPUTFILES * $IMFILEINPUTFILESSTEPS))
+export IMFILECHECKTIMEOUT="60"
+
+# Start rsyslog now before adding more files
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+global( workDirectory="./'"$RSYSLOG_DYNNAME"'.work"
+ debug.whitelist="on"
+ debug.files=["imfile.c"])
+
+module(load="../plugins/imfile/.libs/imfile" mode="inotify" pollingInterval="1")
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.dir?/*/*.logfile"
+ Tag="file:" Severity="error" Facility="local7" addMetadata="on")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.alt/alt*file"
+ Tag="file:" Severity="error" Facility="local7" addMetadata="on")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value="'"'"', ")
+ property(name="$!metadata!filename")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+
+#*.* action(type="omfile" file="rsyslog.debug")
+'
+
+# create first directory and file before startup, so ensure we will NOT
+# get an initial inotify notify for it!
+mkdir $RSYSLOG_DYNNAME.input.alt
+#./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.alt/altfile.logfile
+mkdir $RSYSLOG_DYNNAME.input.dir1
+# the following is INVALID, as this is a file, but must be a directory!
+./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir0
+
+startup
+
+for j in $(seq 1 $IMFILEINPUTFILESSTEPS);
+do
+ echo "Loop Num $j"
+
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ mkdir $RSYSLOG_DYNNAME.input.dir$i
+ mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$i
+ touch $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile
+ ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile
+ done
+
+ ls -d $RSYSLOG_DYNNAME.input.*
+
+ # Check correct amount of input files each time
+ IMFILEINPUTFILESALL=$((IMFILEINPUTFILES * j))
+ content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILESALL $IMFILECHECKTIMEOUT
+
+ # Delete all but first!
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ # slow systems (NFS) do not reliably do rm -r (unfortunately...)
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile
+ ./msleep 100
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$i
+ ./msleep 100
+ rm -vrf $RSYSLOG_DYNNAME.input.dir$i
+ done
+
+ # Helps in testbench parallel mode.
+ # Otherwise sometimes directories are not marked deleted in imfile before they get created again.
+ # This is properly a real issue in imfile when FILE IO is high.
+ ./msleep 1000
+done
+
+shutdown_when_empty
+wait_shutdown
+#echo rsyslog.debug:
+#cat rsyslog.debug
+exit_test
diff --git a/tests/imfile-wildcards-dirs.sh b/tests/imfile-wildcards-dirs.sh
new file mode 100755
index 0000000..27572e4
--- /dev/null
+++ b/tests/imfile-wildcards-dirs.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under GPLv3
+. $srcdir/diag.sh check-inotify
+. ${srcdir:=.}/diag.sh init
+export IMFILEINPUTFILES="10"
+export IMFILECHECKTIMEOUT="60"
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+/* Filter out busy debug output, comment out if needed */
+global(
+ debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+)
+
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+
+module( load="../plugins/imfile/.libs/imfile"
+ mode="inotify"
+ PollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.*/*.logfile"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value=", ")
+ property(name="$!metadata!filename")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+# generate input files first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+
+# Start rsyslog now before adding more files
+startup
+
+for i in $(seq 1 $IMFILEINPUTFILES);
+do
+ mkdir $RSYSLOG_DYNNAME.input.dir$i
+ touch $RSYSLOG_DYNNAME.input.dir$i/file.logfile
+ ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir$i/file.logfile
+done
+ls -d $RSYSLOG_DYNNAME.input.*
+
+# Content check with timeout
+content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILES $IMFILECHECKTIMEOUT
+
+for i in $(seq 1 $IMFILEINPUTFILES);
+do
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/
+done
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+exit_test
diff --git a/tests/imfile-wildcards-dirs2.sh b/tests/imfile-wildcards-dirs2.sh
new file mode 100755
index 0000000..449f2ba
--- /dev/null
+++ b/tests/imfile-wildcards-dirs2.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under GPLv3
+. ${srcdir:=.}/diag.sh init
+export IMFILEINPUTFILES="10"
+export IMFILEINPUTFILESSTEPS="5"
+#export IMFILEINPUTFILESALL=$(($IMFILEINPUTFILES * $IMFILEINPUTFILESSTEPS))
+export IMFILECHECKTIMEOUT="60"
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+
+/* Filter out busy debug output, comment out if needed */
+global(
+ debug.whitelist="off"
+ debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]
+)
+
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+
+module( load="../plugins/imfile/.libs/imfile"
+ mode="inotify"
+ PollingInterval="1")
+
+input(type="imfile"
+ File="./'$RSYSLOG_DYNNAME'.input.*/*.logfile"
+ Tag="file:"
+ Severity="error"
+ Facility="local7"
+ addMetadata="on"
+)
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value=", ")
+ property(name="$!metadata!filename")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action(
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt"
+ )
+'
+. $srcdir/diag.sh check-inotify-only
+# generate input files first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+
+# Start rsyslog now before adding more files
+startup
+# sleep a little to give rsyslog a chance to begin processing
+sleep 1
+
+for j in $(seq 1 $IMFILEINPUTFILESSTEPS);
+do
+ echo "Loop Num $j"
+
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ mkdir $RSYSLOG_DYNNAME.input.dir$i
+ touch $RSYSLOG_DYNNAME.input.dir$i/file.logfile
+ ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir$i/file.logfile
+ done
+ ls -d $RSYSLOG_DYNNAME.input.*
+
+ # Check correct amount of input files each time
+ IMFILEINPUTFILESALL=$((IMFILEINPUTFILES * j))
+ content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILESALL $IMFILECHECKTIMEOUT
+
+ # Delete all but first!
+ for i in $(seq 1 $IMFILEINPUTFILES);
+ do
+ rm -rf $RSYSLOG_DYNNAME.input.dir$i/
+ done
+
+ # Helps in testbench parallel mode.
+ # Otherwise sometimes directories are not marked deleted in imfile before they get created again.
+ # This is properly a real issue in imfile when FILE IO is high.
+ ./msleep 1000
+done
+
+# sleep a little to give rsyslog a chance for processing
+sleep 1
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+exit_test
diff --git a/tests/imfile-wildcards.sh b/tests/imfile-wildcards.sh
new file mode 100755
index 0000000..68c1b61
--- /dev/null
+++ b/tests/imfile-wildcards.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under GPLv3
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-inotify
+export IMFILEINPUTFILES="10"
+export IMFILELASTINPUTLINES="3"
+export IMFILECHECKTIMEOUT="60"
+
+mkdir "$RSYSLOG_DYNNAME.work"
+generate_conf
+add_conf '
+# comment out if you need more debug info:
+ global( debug.whitelist="on"
+ debug.files=["imfile.c"])
+
+global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work")
+
+module(load="../plugins/imfile/.libs/imfile"
+ mode="inotify" normalizePath="off")
+
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.*.log" Tag="file:"
+ Severity="error" Facility="local7" addMetadata="on")
+
+input(type="imfile" File="/does/not/exist/*.log" Tag="file:"
+ Severity="error" Facility="local7" addMetadata="on")
+
+template(name="outfmt" type="list") {
+ constant(value="HEADER ")
+ property(name="msg" format="json")
+ constant(value=", filename: ")
+ property(name="$!metadata!filename")
+ constant(value=", fileoffset: ")
+ property(name="$!metadata!fileoffset")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum:" then
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+# generate input files first. Note that rsyslog processes it as
+# soon as it start up (so the file should exist at that point).
+
+imfilebefore=$RSYSLOG_DYNNAME.input.01.log
+./inputfilegen -m 1 > $imfilebefore
+
+# Start rsyslog now before adding more files
+startup
+
+for i in $(seq 2 $IMFILEINPUTFILES);
+do
+ filnbr=$(printf "%2.2d" $i)
+ cp $imfilebefore $RSYSLOG_DYNNAME.input.$filnbr.log
+ imfilebefore=$RSYSLOG_DYNNAME.input.$filnbr.log
+done
+
+# Content check with timeout
+content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILES $IMFILECHECKTIMEOUT
+
+# Add some extra lines to the last log
+./inputfilegen -m $IMFILELASTINPUTLINES > $RSYSLOG_DYNNAME.input.$((IMFILEINPUTFILES + 1)).log
+ls -l $RSYSLOG_DYNNAME.input.*
+
+# Content check with timeout
+content_check_with_count "input.11.log" $IMFILELASTINPUTLINES $IMFILECHECKTIMEOUT
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+# Sort Output file now, and compare full file content
+presort
+
+printf 'HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.01.log, fileoffset: 0
+HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.02.log, fileoffset: 0
+HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.03.log, fileoffset: 0
+HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.04.log, fileoffset: 0
+HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.05.log, fileoffset: 0
+HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.06.log, fileoffset: 0
+HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.07.log, fileoffset: 0
+HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.08.log, fileoffset: 0
+HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.09.log, fileoffset: 0
+HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.10.log, fileoffset: 0
+HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.11.log, fileoffset: 0
+HEADER msgnum:00000001:, filename: ./'$RSYSLOG_DYNNAME'.input.11.log, fileoffset: 17
+HEADER msgnum:00000002:, filename: ./'$RSYSLOG_DYNNAME'.input.11.log, fileoffset: 34\n' | cmp - $RSYSLOG_DYNNAME.presort
+if [ ! $? -eq 0 ]; then
+ echo "FAIL: invalid output generated, $RSYSLOG_DYNNAME.presort is:"
+ echo "File contents:"
+ cat -n $RSYSLOG_DYNNAME.presort
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imhiredis-queue-lpop-vg.sh b/tests/imhiredis-queue-lpop-vg.sh
new file mode 100755
index 0000000..1d4c5c1
--- /dev/null
+++ b/tests/imhiredis-queue-lpop-vg.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/imhiredis-queue-lpop.sh
diff --git a/tests/imhiredis-queue-lpop.sh b/tests/imhiredis-queue-lpop.sh
new file mode 100755
index 0000000..3ded2fc
--- /dev/null
+++ b/tests/imhiredis-queue-lpop.sh
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+. ${srcdir:=.}/diag.sh init
+
+start_redis
+
+redis_command "RPUSH mykey message1"
+redis_command "RPUSH mykey message2"
+redis_command "RPUSH mykey message3"
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/imhiredis/.libs/imhiredis")
+template(name="outfmt" type="string" string="%$/num% %msg%\n")
+
+
+input(type="imhiredis"
+ server="127.0.0.1"
+ port="'$REDIS_RANDOM_PORT'"
+ key="mykey"
+ mode="queue"
+ uselpop="on"
+ ruleset="redis")
+
+ruleset(name="redis") {
+ set $/num = cnum($/num + 1);
+ action(type="omfile"
+ file="'$RSYSLOG_OUT_LOG'"
+ template="outfmt")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+stop_redis
+
+# Same order
+content_check '1 message1'
+content_check '2 message2'
+content_check '3 message3'
+
+# Removes generated configuration file, log and pid files
+cleanup_redis
+
+exit_test
diff --git a/tests/imhiredis-queue-vg.sh b/tests/imhiredis-queue-vg.sh
new file mode 100755
index 0000000..7298611
--- /dev/null
+++ b/tests/imhiredis-queue-vg.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/imhiredis-queue.sh
diff --git a/tests/imhiredis-queue.sh b/tests/imhiredis-queue.sh
new file mode 100755
index 0000000..da1ef14
--- /dev/null
+++ b/tests/imhiredis-queue.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+. ${srcdir:=.}/diag.sh init
+
+start_redis
+
+redis_command "RPUSH mykey message1"
+redis_command "RPUSH mykey message2"
+redis_command "RPUSH mykey message3"
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/imhiredis/.libs/imhiredis")
+template(name="outfmt" type="string" string="%$/num% %msg%\n")
+
+
+input(type="imhiredis"
+ server="127.0.0.1"
+ port="'$REDIS_RANDOM_PORT'"
+ key="mykey"
+ mode="queue"
+ ruleset="redis")
+
+ruleset(name="redis") {
+ set $/num = cnum($/num + 1);
+ action(type="omfile"
+ file="'$RSYSLOG_OUT_LOG'"
+ template="outfmt")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+stop_redis
+
+# Opposite order
+content_check '1 message3'
+content_check '2 message2'
+content_check '3 message1'
+
+# Removes generated configuration file, log and pid files
+cleanup_redis
+
+exit_test
diff --git a/tests/imhiredis-redis-restart-vg.sh b/tests/imhiredis-redis-restart-vg.sh
new file mode 100755
index 0000000..19b12f5
--- /dev/null
+++ b/tests/imhiredis-redis-restart-vg.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/imhiredis-redis-restart.sh
diff --git a/tests/imhiredis-redis-restart.sh b/tests/imhiredis-redis-restart.sh
new file mode 100755
index 0000000..6d997d8
--- /dev/null
+++ b/tests/imhiredis-redis-restart.sh
@@ -0,0 +1,69 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+. ${srcdir:=.}/diag.sh init
+
+# Start redis once to be able to generate configuration
+start_redis
+
+redis_command "RPUSH mykey message1"
+redis_command "RPUSH mykey message2"
+redis_command "RPUSH mykey message3"
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/imhiredis/.libs/imhiredis")
+template(name="outfmt" type="string" string="%$/num% %msg%\n")
+
+
+input(type="imhiredis"
+ server="127.0.0.1"
+ port="'$REDIS_RANDOM_PORT'"
+ key="mykey"
+ mode="queue"
+ ruleset="redis")
+
+ruleset(name="redis") {
+ set $/num = cnum($/num + 1);
+ action(type="omfile"
+ file="'$RSYSLOG_OUT_LOG'"
+ template="outfmt")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+wait_content '3 message1'
+
+# Stop Redis and wait a short moment for imhiredis to notice Redis went down
+stop_redis
+rst_msleep 1500
+start_redis
+
+redis_command "RPUSH mykey message4"
+redis_command "RPUSH mykey message5"
+redis_command "RPUSH mykey message6"
+
+wait_content '4 message6'
+
+shutdown_when_empty
+wait_shutdown
+
+stop_redis
+
+content_check '1 message3'
+content_check '2 message2'
+content_check '3 message1'
+content_check 'sleeping 10 seconds before retrying'
+content_check '4 message6'
+content_check '5 message5'
+content_check '6 message4'
+
+# Removes generated configuration file, log and pid files
+cleanup_redis
+
+exit_test
diff --git a/tests/imhiredis-redis-start-after-vg.sh b/tests/imhiredis-redis-start-after-vg.sh
new file mode 100755
index 0000000..689f501
--- /dev/null
+++ b/tests/imhiredis-redis-start-after-vg.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/imhiredis-redis-start-after.sh
diff --git a/tests/imhiredis-redis-start-after.sh b/tests/imhiredis-redis-start-after.sh
new file mode 100755
index 0000000..2ef39dd
--- /dev/null
+++ b/tests/imhiredis-redis-start-after.sh
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+. ${srcdir:=.}/diag.sh init
+
+# Start redis once to be able to generate configuration
+start_redis
+stop_redis
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/imhiredis/.libs/imhiredis")
+template(name="outfmt" type="string" string="%$/num% %msg%\n")
+
+
+input(type="imhiredis"
+ server="127.0.0.1"
+ port="'$REDIS_RANDOM_PORT'"
+ key="mykey"
+ mode="queue"
+ ruleset="redis")
+
+ruleset(name="redis") {
+ set $/num = cnum($/num + 1);
+ action(type="omfile"
+ file="'$RSYSLOG_OUT_LOG'"
+ template="outfmt")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+start_redis
+redis_command "RPUSH mykey message1"
+redis_command "RPUSH mykey message2"
+redis_command "RPUSH mykey message3"
+
+wait_content '1 message3'
+
+shutdown_when_empty
+wait_shutdown
+
+stop_redis
+
+content_check '1 message3'
+content_check '2 message2'
+content_check '3 message1'
+
+# Removes generated configuration file, log and pid files
+cleanup_redis
+
+exit_test
diff --git a/tests/imhiredis-stream-consumerGroup-ack-vg.sh b/tests/imhiredis-stream-consumerGroup-ack-vg.sh
new file mode 100755
index 0000000..ee454fc
--- /dev/null
+++ b/tests/imhiredis-stream-consumerGroup-ack-vg.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/imhiredis-stream-consumerGroup-ack.sh
diff --git a/tests/imhiredis-stream-consumerGroup-ack.sh b/tests/imhiredis-stream-consumerGroup-ack.sh
new file mode 100755
index 0000000..964a781
--- /dev/null
+++ b/tests/imhiredis-stream-consumerGroup-ack.sh
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+. ${srcdir:=.}/diag.sh init
+
+start_redis
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/imhiredis/.libs/imhiredis")
+template(name="outfmt" type="string" string="%$/num% %$!msg%\n")
+
+
+input(type="imhiredis"
+ server="127.0.0.1"
+ port="'$REDIS_RANDOM_PORT'"
+ key="mystream"
+ mode="stream"
+ stream.consumerGroup="mygroup"
+ stream.consumerName="myName"
+ ruleset="redis")
+
+ruleset(name="redis") {
+ set $/num = cnum($/num + 1);
+ action(type="omfile"
+ file="'$RSYSLOG_OUT_LOG'"
+ template="outfmt")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+redis_command "XADD mystream * msg message1"
+redis_command "XADD mystream * msg message2"
+redis_command "XADD mystream * msg message3"
+
+shutdown_when_empty
+wait_shutdown
+
+output="$(redis_command 'hello 3\nXINFO groups mystream' | grep 'pending')"
+
+if [ -z "$output" ]; then
+ echo "Could not get group result from redis, cannot tell if entries ware acknowledged!"
+ error_exit 1
+fi
+
+if ! echo "$output" | grep -q "pending 0"; then
+ echo "ERROR: entries werent acknowledged!"
+ echo "ERROR: output from Redis is '$output'"
+ echo "ERROR: expected 'pending 0'"
+ error_exit 1
+fi
+
+stop_redis
+
+content_check '1 message1'
+content_check '2 message2'
+content_check '3 message3'
+
+# Removes generated configuration file, log and pid files
+cleanup_redis
+
+exit_test
diff --git a/tests/imhiredis-stream-consumerGroup-noack-vg.sh b/tests/imhiredis-stream-consumerGroup-noack-vg.sh
new file mode 100755
index 0000000..fa05d58
--- /dev/null
+++ b/tests/imhiredis-stream-consumerGroup-noack-vg.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/imhiredis-stream-consumerGroup-noack.sh
diff --git a/tests/imhiredis-stream-consumerGroup-noack.sh b/tests/imhiredis-stream-consumerGroup-noack.sh
new file mode 100755
index 0000000..3b2a555
--- /dev/null
+++ b/tests/imhiredis-stream-consumerGroup-noack.sh
@@ -0,0 +1,68 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+. ${srcdir:=.}/diag.sh init
+
+start_redis
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/imhiredis/.libs/imhiredis")
+template(name="outfmt" type="string" string="%$/num% %$!msg%\n")
+
+
+input(type="imhiredis"
+ server="127.0.0.1"
+ port="'$REDIS_RANDOM_PORT'"
+ key="mystream"
+ mode="stream"
+ stream.consumerGroup="mygroup"
+ stream.consumerName="myName"
+ stream.consumerACK="off"
+ ruleset="redis")
+
+ruleset(name="redis") {
+ set $/num = cnum($/num + 1);
+ action(type="omfile"
+ file="'$RSYSLOG_OUT_LOG'"
+ template="outfmt")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+redis_command "XADD mystream * msg message1"
+redis_command "XADD mystream * msg message2"
+redis_command "XADD mystream * msg message3"
+
+shutdown_when_empty
+wait_shutdown
+
+output="$(redis_command 'hello 3\nXINFO groups mystream' | grep 'pending')"
+
+if [ -z "$output" ]; then
+ echo "Could not get group result from redis, cannot tell if entries ware acknowledged!"
+ error_exit 1
+fi
+
+if ! echo "$output" | grep -q "pending 3"; then
+ echo "ERROR: entries were acknowledged, they shouldn't have!"
+ echo "ERROR: output from Redis is '$output'"
+ echo "ERROR: expected 'pending 3'"
+ error_exit 1
+fi
+
+stop_redis
+
+content_check '1 message1'
+content_check '2 message2'
+content_check '3 message3'
+
+# Removes generated configuration file, log and pid files
+cleanup_redis
+
+exit_test
diff --git a/tests/imhiredis-stream-consumerGroup-reclaim-vg.sh b/tests/imhiredis-stream-consumerGroup-reclaim-vg.sh
new file mode 100755
index 0000000..f287e66
--- /dev/null
+++ b/tests/imhiredis-stream-consumerGroup-reclaim-vg.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/imhiredis-stream-consumerGroup-reclaim.sh
diff --git a/tests/imhiredis-stream-consumerGroup-reclaim.sh b/tests/imhiredis-stream-consumerGroup-reclaim.sh
new file mode 100755
index 0000000..b2c6428
--- /dev/null
+++ b/tests/imhiredis-stream-consumerGroup-reclaim.sh
@@ -0,0 +1,83 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+. ${srcdir:=.}/diag.sh init
+
+start_redis
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/imhiredis/.libs/imhiredis")
+template(name="outfmt" type="string" string="%$/num% %$!msg%\n")
+
+
+input(type="imhiredis"
+ server="127.0.0.1"
+ port="'$REDIS_RANDOM_PORT'"
+ key="mystream"
+ mode="stream"
+ stream.consumerGroup="mygroup"
+ stream.consumerName="myName"
+ stream.autoclaimIdleTime="5000" #5 seconds
+ ruleset="redis")
+
+ruleset(name="redis") {
+ set $/num = cnum($/num + 1);
+ action(type="omfile"
+ file="'$RSYSLOG_OUT_LOG'"
+ template="outfmt")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+
+redis_command "XADD mystream * msg message1"
+redis_command "XADD mystream * msg message2"
+redis_command "XADD mystream * msg message3"
+redis_command "XADD mystream * msg message4"
+redis_command "XADD mystream * msg message5"
+redis_command "XADD mystream * msg message6"
+
+redis_command "XGROUP CREATE mystream mygroup 0-0"
+# Read and claim message1 and message2
+redis_command "XREADGROUP GROUP mygroup otherConsumer COUNT 2 STREAMS mystream >"
+rst_msleep 5500
+# Read and claim message3 and message4
+redis_command "XREADGROUP GROUP mygroup otherConsumer COUNT 2 STREAMS mystream >"
+
+startup
+
+shutdown_when_empty
+wait_shutdown
+
+output="$(redis_command 'hello 3\nXINFO groups mystream' | grep 'pending')"
+
+if [ -z "$output" ]; then
+ echo "Could not get group result from redis, cannot tell if entries ware acknowledged!"
+ error_exit 1
+fi
+
+# Should still have 2 pending messages: message3 and message4
+if ! echo "$output" | grep -q "pending 2"; then
+ echo "ERROR: entries weren't acknowledged!"
+ echo "ERROR: output from Redis is '$output'"
+ echo "ERROR: expected 'pending 2'"
+ error_exit 1
+fi
+
+stop_redis
+
+# Should reclaim message1 and message2
+# then claim and acknowledge message5 and message6 normally
+content_check '1 message1'
+content_check '2 message2'
+content_check '3 message5'
+content_check '4 message6'
+
+# Removes generated configuration file, log and pid files
+cleanup_redis
+
+exit_test
diff --git a/tests/imhiredis-stream-from-beginning-vg.sh b/tests/imhiredis-stream-from-beginning-vg.sh
new file mode 100755
index 0000000..5ea573b
--- /dev/null
+++ b/tests/imhiredis-stream-from-beginning-vg.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/imhiredis-stream-from-beginning.sh
diff --git a/tests/imhiredis-stream-from-beginning.sh b/tests/imhiredis-stream-from-beginning.sh
new file mode 100755
index 0000000..f007d3a
--- /dev/null
+++ b/tests/imhiredis-stream-from-beginning.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+. ${srcdir:=.}/diag.sh init
+
+start_redis
+
+# WILL be logged by Rsyslog
+redis_command "XADD mystream * msg message1"
+redis_command "XADD mystream * msg message2"
+redis_command "XADD mystream * msg message3"
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/imhiredis/.libs/imhiredis")
+template(name="outfmt" type="string" string="%$/num% %$!msg%\n")
+
+
+input(type="imhiredis"
+ server="127.0.0.1"
+ port="'$REDIS_RANDOM_PORT'"
+ key="mystream"
+ mode="stream"
+ stream.readFrom="0-0"
+ ruleset="redis")
+
+ruleset(name="redis") {
+ set $/num = cnum($/num + 1);
+ action(type="omfile"
+ file="'$RSYSLOG_OUT_LOG'"
+ template="outfmt")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+redis_command "XADD mystream * msg message4"
+redis_command "XADD mystream * msg message5"
+redis_command "XADD mystream * msg message6"
+
+shutdown_when_empty
+wait_shutdown
+
+stop_redis
+
+content_check '1 message1'
+content_check '2 message2'
+content_check '3 message3'
+content_check '4 message4'
+content_check '5 message5'
+content_check '6 message6'
+
+# Removes generated configuration file, log and pid files
+cleanup_redis
+
+exit_test
diff --git a/tests/imhiredis-stream-vg.sh b/tests/imhiredis-stream-vg.sh
new file mode 100755
index 0000000..b3e5d59
--- /dev/null
+++ b/tests/imhiredis-stream-vg.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/imhiredis-stream.sh
diff --git a/tests/imhiredis-stream.sh b/tests/imhiredis-stream.sh
new file mode 100755
index 0000000..5a014ab
--- /dev/null
+++ b/tests/imhiredis-stream.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+. ${srcdir:=.}/diag.sh init
+
+start_redis
+
+# Won't be logged by Rsyslog
+redis_command "XADD mystream * msg message1"
+redis_command "XADD mystream * msg message2"
+redis_command "XADD mystream * msg message3"
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/imhiredis/.libs/imhiredis")
+template(name="outfmt" type="string" string="%$/num% %$!msg%\n")
+
+
+input(type="imhiredis"
+ server="127.0.0.1"
+ port="'$REDIS_RANDOM_PORT'"
+ key="mystream"
+ mode="stream"
+ ruleset="redis")
+
+ruleset(name="redis") {
+ set $/num = cnum($/num + 1);
+ action(type="omfile"
+ file="'$RSYSLOG_OUT_LOG'"
+ template="outfmt")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+redis_command "XADD mystream * msg message4"
+redis_command "XADD mystream * msg message5"
+redis_command "XADD mystream * msg message6"
+
+shutdown_when_empty
+wait_shutdown
+
+stop_redis
+
+check_not_present "message1"
+check_not_present "message2"
+check_not_present "message3"
+
+content_check '1 message4'
+content_check '2 message5'
+content_check '3 message6'
+
+# Removes generated configuration file, log and pid files
+cleanup_redis
+
+exit_test
diff --git a/tests/imhiredis-subscribe-vg.sh b/tests/imhiredis-subscribe-vg.sh
new file mode 100755
index 0000000..b57709d
--- /dev/null
+++ b/tests/imhiredis-subscribe-vg.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/imhiredis-subscribe.sh
diff --git a/tests/imhiredis-subscribe.sh b/tests/imhiredis-subscribe.sh
new file mode 100755
index 0000000..ec098e7
--- /dev/null
+++ b/tests/imhiredis-subscribe.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+# added 2023-04-20 by Théo Bertin, released under ASL 2.0
+## Uncomment for debugging
+#export RS_REDIR=-d
+
+. ${srcdir:=.}/diag.sh init
+
+start_redis
+
+# Won't be logged by Rsyslog
+redis_command "PUBLISH mychannel message1"
+redis_command "PUBLISH mychannel message2"
+redis_command "PUBLISH mychannel message3"
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/imhiredis/.libs/imhiredis")
+template(name="outfmt" type="string" string="%$/num% %msg%\n")
+
+
+input(type="imhiredis"
+ server="127.0.0.1"
+ port="'$REDIS_RANDOM_PORT'"
+ key="mychannel"
+ mode="subscribe"
+ ruleset="redis")
+
+ruleset(name="redis") {
+ set $/num = cnum($/num + 1);
+ action(type="omfile"
+ file="'$RSYSLOG_OUT_LOG'"
+ template="outfmt")
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+redis_command "PUBLISH mychannel message4"
+redis_command "PUBLISH mychannel message5"
+redis_command "PUBLISH mychannel message6"
+
+shutdown_when_empty
+wait_shutdown
+
+stop_redis
+
+check_not_present "message1"
+check_not_present "message2"
+check_not_present "message3"
+
+content_check '1 message4'
+content_check '2 message5'
+content_check '3 message6'
+
+# Removes generated configuration file, log and pid files
+cleanup_redis
+
+exit_test
diff --git a/tests/imhttp-getrequest-file-vg.sh b/tests/imhttp-getrequest-file-vg.sh
new file mode 100755
index 0000000..d7cb76c
--- /dev/null
+++ b/tests/imhttp-getrequest-file-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+#export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all"
+source ${srcdir:-.}/imhttp-getrequest-file.sh
diff --git a/tests/imhttp-getrequest-file.sh b/tests/imhttp-getrequest-file.sh
new file mode 100755
index 0000000..73ed46f
--- /dev/null
+++ b/tests/imhttp-getrequest-file.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+IMHTTP_PORT="$(get_free_port)"
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+module(load="../contrib/imhttp/.libs/imhttp"
+ ports="'$IMHTTP_PORT'"
+ documentroot="'$srcdir'/testsuites/docroot")
+'
+startup
+curl -s http://localhost:$IMHTTP_PORT/file.txt > "$RSYSLOG_OUT_LOG"
+shutdown_when_empty
+echo "file name: $RSYSLOG_OUT_LOG"
+content_check "This is a test of get page"
+exit_test
diff --git a/tests/imhttp-post-payload-basic-auth-vg.sh b/tests/imhttp-post-payload-basic-auth-vg.sh
new file mode 100755
index 0000000..4762484
--- /dev/null
+++ b/tests/imhttp-post-payload-basic-auth-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+#export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all"
+source ${srcdir:-.}/imhttp-post-payload-basic-auth.sh
diff --git a/tests/imhttp-post-payload-basic-auth.sh b/tests/imhttp-post-payload-basic-auth.sh
new file mode 100755
index 0000000..e88e7a4
--- /dev/null
+++ b/tests/imhttp-post-payload-basic-auth.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+IMHTTP_PORT="$(get_free_port)"
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="msg")
+ constant(value=" - ")
+ constant(value="{ baz: ")
+ property(name="$!metadata!httpheaders!baz")
+ constant(value=", daddle: ")
+ property(name="$!metadata!httpheaders!daddle")
+ constant(value=", fiddle: ")
+ property(name="$!metadata!httpheaders!fiddle")
+ constant(value=" }")
+ constant(value=" - ")
+ constant(value=" !metadata: ")
+ property(name="$!metadata")
+ constant(value="\n")
+}
+
+#
+# note htpasswd file contains entry:
+# user1:1234
+#
+module(load="../contrib/imhttp/.libs/imhttp"
+ ports="'$IMHTTP_PORT'")
+input(type="imhttp" endpoint="/postrequest"
+ ruleset="ruleset"
+ addmetadata="on"
+ basicauthfile="'$srcdir'/testsuites/htpasswd")
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+# validate invalid passwd
+ret=$(curl -v -s -H Content-Type:application/json -H "BAZ: skat" -H "daddle: doodle" -H "fiddle: faddle" \
+ --user user1:badpass --write-out '%{http_code}' \
+ http://localhost:$IMHTTP_PORT/postrequest -d '[{"foo":"bar","bar":"foo"},{"one":"two","three":"four"}]')
+
+echo "response: $ret"
+if ! ( echo "$ret" | grep "Error 401: Unauthorized" )
+then
+ echo "ERROR: should not be unauthorized"
+ error_exit 1
+fi
+
+# validate correct password
+curl -s -H Content-Type:application/json -H "BAZ: skat" -H "daddle: doodle" -H "fiddle: faddle" \
+ --user user1:1234 --write-out '%{http_code}' \
+ http://localhost:$IMHTTP_PORT/postrequest -d '[{"foo":"bar","bar":"foo"},{"one":"two","three":"four"}]'
+
+wait_queueempty
+echo "doing shutdown"
+shutdown_when_empty
+wait_shutdown
+echo "file name: $RSYSLOG_OUT_LOG"
+content_check '[{"foo":"bar","bar":"foo"},{"one":"two","three":"four"}] - { baz: skat, daddle: doodle, fiddle: faddle }'
+exit_test
diff --git a/tests/imhttp-post-payload-compress-vg.sh b/tests/imhttp-post-payload-compress-vg.sh
new file mode 100755
index 0000000..3b7051c
--- /dev/null
+++ b/tests/imhttp-post-payload-compress-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+#export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all"
+source ${srcdir:-.}/imhttp-post-payload-compress.sh
diff --git a/tests/imhttp-post-payload-compress.sh b/tests/imhttp-post-payload-compress.sh
new file mode 100755
index 0000000..1278c11
--- /dev/null
+++ b/tests/imhttp-post-payload-compress.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUG="debug"
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+IMHTTP_PORT="$(get_free_port)"
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+module(load="../contrib/imhttp/.libs/imhttp"
+ ports="'$IMHTTP_PORT'")
+#input(type="imhttp" endpoint="/postrequest" ruleset="ruleset" disablelfdelimiter="on")
+input(type="imhttp" endpoint="/postrequest" ruleset="ruleset")
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+NUMMESSAGES=50
+
+for (( i=1; i<=NUMMESSAGES; i++ ))
+do
+ echo '[{"foo":"bar","bar":"foo"},{"one":"two","three":"four"}]' | gzip | curl -si --data-binary @- -H "Content-Encoding: gzip" http://localhost:$IMHTTP_PORT/postrequest
+done
+wait_queueempty
+shutdown_when_empty
+echo "file name: $RSYSLOG_OUT_LOG"
+content_count_check '[{"foo":"bar","bar":"foo"},{"one":"two","three":"four"}]' $NUMMESSAGES
+exit_test
diff --git a/tests/imhttp-post-payload-large-vg.sh b/tests/imhttp-post-payload-large-vg.sh
new file mode 100755
index 0000000..7bd3b74
--- /dev/null
+++ b/tests/imhttp-post-payload-large-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+#export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all"
+source ${srcdir:-.}/imhttp-post-payload-large.sh
diff --git a/tests/imhttp-post-payload-large.sh b/tests/imhttp-post-payload-large.sh
new file mode 100755
index 0000000..7323eec
--- /dev/null
+++ b/tests/imhttp-post-payload-large.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+IMHTTP_PORT="$(get_free_port)"
+add_conf '
+#template(name="outfmt" type="string" string="%msg%\n")
+template(name="outfmt" type="string" string="%rawmsg%\n")
+module(load="../contrib/imhttp/.libs/imhttp"
+ ports="'$IMHTTP_PORT'")
+input(type="imhttp" endpoint="/postrequest" ruleset="ruleset")
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+NUMMESSAGES=25
+DATA_SOURCE=$srcdir/testsuites/imhttp-large-data.txt
+for (( i=1; i<=NUMMESSAGES; i++ ))
+do
+ curl -si -X POST -H Content-Type:application/json http://localhost:$IMHTTP_PORT/postrequest --data-binary @$DATA_SOURCE &
+ pids[${i}]=$!
+done
+
+# wait for all pids
+for pid in ${pids[*]};
+do
+ wait $pid
+# echo "$pid cleaned up"
+done
+
+sleep 2
+wait_queueempty
+echo "doing shutdown"
+shutdown_when_empty
+wait_shutdown
+
+# reference file for comparison
+TMPFILE=${RSYSLOG_DYNNAME}.tmp
+for (( i=1; i <= NUMMESSAGES; i++ ))
+do
+ cat $DATA_SOURCE >> $TMPFILE
+done
+
+if diff -q $TMPFILE $RSYSLOG_OUT_LOG;
+then
+ echo "files match!"
+ exit_test
+else
+ error_exit 1
+fi
diff --git a/tests/imhttp-post-payload-multi-lf-vg.sh b/tests/imhttp-post-payload-multi-lf-vg.sh
new file mode 100755
index 0000000..add90d6
--- /dev/null
+++ b/tests/imhttp-post-payload-multi-lf-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+#export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all"
+source ${srcdir:-.}/imhttp-post-payload-multi-lf.sh
diff --git a/tests/imhttp-post-payload-multi-lf.sh b/tests/imhttp-post-payload-multi-lf.sh
new file mode 100755
index 0000000..fb367b5
--- /dev/null
+++ b/tests/imhttp-post-payload-multi-lf.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+
+#export RSYSLOG_DEBUG="Debug"
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+IMHTTP_PORT="$(get_free_port)"
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+module(load="../contrib/imhttp/.libs/imhttp" ports="'$IMHTTP_PORT'")
+
+input(type="imhttp" endpoint="/postrequest" disableLFdelimiter="on" ruleset="ruleset")
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+NUMMESSAGES=50
+
+for (( i=1; i<=NUMMESSAGES; i++ ))
+do
+ curl -si -H Content-Type:application/json http://localhost:$IMHTTP_PORT/postrequest -d $'{"foo":"bar","bar":"foo"}\n{"one":"two","three":"four"}'
+done
+shutdown_when_empty
+echo "file name: $RSYSLOG_OUT_LOG"
+content_count_check '{"foo":"bar","bar":"foo"}' $NUMMESSAGES
+content_count_check '{"one":"two","three":"four"}' $NUMMESSAGES
+exit_test
diff --git a/tests/imhttp-post-payload-multi-vg.sh b/tests/imhttp-post-payload-multi-vg.sh
new file mode 100755
index 0000000..0a736af
--- /dev/null
+++ b/tests/imhttp-post-payload-multi-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+#export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all"
+source ${srcdir:-.}/imhttp-post-payload-multi.sh
diff --git a/tests/imhttp-post-payload-multi.sh b/tests/imhttp-post-payload-multi.sh
new file mode 100755
index 0000000..ba3bfa2
--- /dev/null
+++ b/tests/imhttp-post-payload-multi.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+IMHTTP_PORT="$(get_free_port)"
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+module(load="../contrib/imhttp/.libs/imhttp"
+ liboptions=[ "listening_ports='$IMHTTP_PORT'" ] )
+input(type="imhttp" endpoint="/postrequest" ruleset="ruleset")
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+NUMMESSAGES=50
+for (( i=1; i<=NUMMESSAGES; i++ ))
+do
+ curl -si -H Content-Type:application/json http://localhost:$IMHTTP_PORT/postrequest -d $'{"foo":"bar","bar":"foo"}\n{"one":"two","three":"four"}'
+done
+wait_queueempty
+shutdown_when_empty
+echo "file name: $RSYSLOG_OUT_LOG"
+content_count_check '{"foo":"bar","bar":"foo"}' $NUMMESSAGES
+content_count_check '{"one":"two","three":"four"}' $NUMMESSAGES
+exit_test
diff --git a/tests/imhttp-post-payload-query-params-vg.sh b/tests/imhttp-post-payload-query-params-vg.sh
new file mode 100755
index 0000000..d71f68b
--- /dev/null
+++ b/tests/imhttp-post-payload-query-params-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+#export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all"
+source ${srcdir:-.}/imhttp-post-payload-query-params.sh*
diff --git a/tests/imhttp-post-payload-query-params.sh b/tests/imhttp-post-payload-query-params.sh
new file mode 100755
index 0000000..ae6d61d
--- /dev/null
+++ b/tests/imhttp-post-payload-query-params.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+IMHTTP_PORT="$(get_free_port)"
+add_conf '
+template(name="all" type="string" string="%msg% headers: %$!metadata%\n")
+template(name="outfmt" type="list") {
+ property(name="msg")
+ constant(value=" - ")
+ constant(value="{ baz: ")
+ property(name="$!metadata!httpheaders!baz")
+ constant(value=", daddle: ")
+ property(name="$!metadata!httpheaders!daddle")
+ constant(value=", fiddle: ")
+ property(name="$!metadata!httpheaders!fiddle")
+ constant(value=" }")
+ constant(value=" - ")
+ constant(value=" !metadata: ")
+ property(name="$!metadata")
+ constant(value="\n")
+}
+
+module(load="../contrib/imhttp/.libs/imhttp"
+ ports="'$IMHTTP_PORT'")
+input(type="imhttp" endpoint="/postrequest" ruleset="ruleset" addmetadata="on")
+ruleset(name="ruleset") {
+ #action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="all")
+}
+'
+startup
+NUMMESSAGES=100
+for (( i=1; i<=NUMMESSAGES; i++ ))
+do
+ curl -si -H Content-Type:application/json -H "BAZ: skat" -H "daddle: doodle" -H "fiddle: faddle" \
+ "http://localhost:$IMHTTP_PORT/postrequest?foo=bar;bar=foo&one=3" --data '[{"foo":"bar","bar":"foo"},{"one":"two","three":"four"}]' &
+done
+sleep 2
+wait_queueempty
+echo "doing shutdown"
+shutdown_when_empty
+wait_shutdown
+echo "file name: $RSYSLOG_OUT_LOG"
+#content_count_check '[{"foo":"bar","bar":"foo"},{"one":"two","three":"four"}] - { baz: skat, daddle: doodle, fiddle: faddle }' $NUMMESSAGES
+content_count_check '"queryparams": { "foo": "bar", "bar": "foo", "one": "3" }' $NUMMESSAGES
+exit_test
diff --git a/tests/imhttp-post-payload-vg.sh b/tests/imhttp-post-payload-vg.sh
new file mode 100755
index 0000000..4567edc
--- /dev/null
+++ b/tests/imhttp-post-payload-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+#export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all"
+source ${srcdir:-.}/imhttp-post-payload.sh
diff --git a/tests/imhttp-post-payload.sh b/tests/imhttp-post-payload.sh
new file mode 100755
index 0000000..2d1af19
--- /dev/null
+++ b/tests/imhttp-post-payload.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+IMHTTP_PORT="$(get_free_port)"
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+module(load="../contrib/imhttp/.libs/imhttp"
+ ports="'$IMHTTP_PORT'")
+input(type="imhttp" endpoint="/postrequest" ruleset="ruleset")
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+sleep 1
+NUMMESSAGES=50
+for (( i=1; i<=NUMMESSAGES; i++ ))
+do
+ curl -si -H Content-Type:application/json http://localhost:$IMHTTP_PORT/postrequest -d '[{"foo":"bar","bar":"foo"},{"one":"two","three":"four"}]' &
+ pids[${i}]=$!
+done
+
+# wait for all pids
+for pid in ${pids[*]};
+do
+ wait $pid
+done
+
+sleep 2
+wait_queueempty
+echo "doing shutdown"
+shutdown_when_empty
+wait_shutdown
+echo "file name: $RSYSLOG_OUT_LOG"
+content_count_check '[{"foo":"bar","bar":"foo"},{"one":"two","three":"four"}]' $NUMMESSAGES
+exit_test
diff --git a/tests/imjournal-basic-vg.sh b/tests/imjournal-basic-vg.sh
new file mode 100755
index 0000000..bda9288
--- /dev/null
+++ b/tests/imjournal-basic-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imjournal-basic.sh
diff --git a/tests/imjournal-basic.sh b/tests/imjournal-basic.sh
new file mode 100755
index 0000000..53d9d7f
--- /dev/null
+++ b/tests/imjournal-basic.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# This test injects a message and checks if it is received by
+# imjournal. We use a special test string which we do not expect
+# to be present in the regular log stream. So we do not expect that
+# any other journal content matches our test message. We skip the
+# test in case message does not make it even to journal which may
+# sometimes happen in some environments.
+# addd 2017-10-25 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh require-journalctl
+generate_conf
+add_conf '
+module(load="../plugins/imjournal/.libs/imjournal" IgnorePreviousMessages="on"
+ RateLimit.Burst="1000000")
+
+template(name="outfmt" type="string" string="%msg%\n")
+action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+TESTMSG="TestBenCH-RSYSLog imjournal This is a test message - $(date +%s) - $RSYSLOG_DYNNAME"
+
+startup
+
+printf 'a quick glimpse at journal content at rsyslog startup:\n'
+journalctl -n 20 --no-pager
+printf '\n\n'
+
+printf '++++++++++++++++++++++ Printing to the journal! +++++++++++++++++++++++++\n'
+# inject message into journal and check that it is recorded
+./journal_print "$TESTMSG"
+journal_write_state=$?
+if [ $journal_write_state -ne 0 ]; then
+ printf 'SKIP: journal_print returned state %d writing message: %s\n' "$journal_write_state" "$TESTMSG"
+ printf 'skipping test, journal probably not working\n'
+ exit 77
+fi
+
+# check state later - we must not terminate the test until we have terminated rsyslog
+
+# give the journal ~5 minutes to forward the message, see
+# https://github.com/rsyslog/rsyslog/issues/2564#issuecomment-435849660
+content_check_with_count "$TESTMSG" 1 300
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+check_journal_testmsg_received
+exit_test
diff --git a/tests/imjournal-statefile-vg.sh b/tests/imjournal-statefile-vg.sh
new file mode 100755
index 0000000..f1cdf2a
--- /dev/null
+++ b/tests/imjournal-statefile-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imjournal-statefile.sh
diff --git a/tests/imjournal-statefile.sh b/tests/imjournal-statefile.sh
new file mode 100755
index 0000000..3ad05d3
--- /dev/null
+++ b/tests/imjournal-statefile.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+# This test injects a message and checks if it is received by
+# imjournal. We use a special test string which we do not expect
+# to be present in the regular log stream. So we do not expect that
+# any other journal content matches our test message. We skip the
+# test in case message does not make it even to journal which may
+# sometimes happen in some environments.
+# addd 2017-10-25 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh require-journalctl
+generate_conf
+add_conf '
+global(workDirectory="'$RSYSLOG_DYNNAME.spool'")
+module(load="../plugins/imjournal/.libs/imjournal" StateFile="imjournal.state"
+ # we turn off rate-limiting, else we may miss our test message:
+ RateLimit.interval="0"
+ )
+
+template(name="outfmt" type="string" string="%msg%\n")
+action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+TESTMSG="TestBenCH-RSYSLog imjournal This is a test message - $(date +%s) - $RSYSLOG_DYNNAME"
+./journal_print "$TESTMSG"
+if [ $? -ne 0 ]; then
+ echo "SKIP: failed to put test into journal."
+ error_exit 77
+fi
+
+# sleep 1 to get this test to reliably detect the message
+sleep 1
+
+journalctl -an 200 > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+ echo "SKIP: cannot read journal."
+ error_exit 77
+fi
+
+journalctl -an 200 | grep -qF "$TESTMSG"
+if [ $? -ne 0 ]; then
+ echo "SKIP: cannot find '$TESTMSG' in journal."
+ error_exit 77
+fi
+
+# do first run to process all the stuff already in journal db
+startup
+
+# give the journal ~5 minutes to forward the message, see
+# https://github.com/rsyslog/rsyslog/issues/2564#issuecomment-435849660
+content_check_with_count "$TESTMSG" 1 300
+
+shutdown_when_empty
+wait_shutdown
+
+printf '%s first rsyslogd run done, now restarting\n' "$(tb_timestamp)"
+
+#now do a second which should NOT capture testmsg again
+# craft new testmessage as shutdown condition:
+TESTMSG2="TestBenCH-RSYSLog imjournal This is a test message 2 - $(date +%s) - $RSYSLOG_DYNNAME"
+startup
+./journal_print "$TESTMSG2"
+content_check_with_count "$TESTMSG2" 1 300
+shutdown_when_empty
+wait_shutdown
+
+printf '%s both rsyslogd runs finished, doing final result check\n' "$(tb_timestamp)"
+
+# now check the original one is there
+content_count_check "$TESTMSG" 1
+exit_test
diff --git a/tests/imkafka-backgrounded.sh b/tests/imkafka-backgrounded.sh
new file mode 100755
index 0000000..60bf31b
--- /dev/null
+++ b/tests/imkafka-backgrounded.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+# added 2018-10-24 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+check_command_available kafkacat
+export KEEP_KAFKA_RUNNING="YES"
+
+export TESTMESSAGES=100000
+export RANDTOPIC=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+# Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only.
+export EXTRA_EXITCHECK=dumpkafkalogs
+export EXTRA_EXIT=kafka
+
+echo Check and Stop previous instances of kafka/zookeeper
+download_kafka
+stop_zookeeper
+stop_kafka
+
+echo Create kafka/zookeeper instance and $RANDTOPIC topic
+start_zookeeper
+start_kafka
+
+create_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+
+module(load="../plugins/imkafka/.libs/imkafka")
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if ($msg contains "msgnum:") then {
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" )
+}
+'
+
+export RSTB_DAEMONIZE="YES"
+startup
+
+injectmsg_kafkacat --wait 1 $TESTMESSAGES -d
+shutdown_when_empty
+wait_shutdown
+
+# Delete topic to remove old traces before
+delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+seq_check 1 $TESTMESSAGES -d
+exit_test
diff --git a/tests/imkafka-config-err-param.sh b/tests/imkafka-config-err-param.sh
new file mode 100755
index 0000000..107a116
--- /dev/null
+++ b/tests/imkafka-config-err-param.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# added 2018-08-29 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+check_command_available kafkacat
+export KEEP_KAFKA_RUNNING="YES"
+
+export TESTMESSAGES=1000
+# Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only.
+export EXTRA_EXITCHECK=dumpkafkalogs
+export EXTRA_EXIT=kafka
+
+export RANDTOPIC=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+
+download_kafka
+stop_zookeeper
+stop_kafka
+start_zookeeper
+start_kafka
+
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+
+module(load="../plugins/imkafka/.libs/imkafka")
+/* Polls messages from kafka server!*/
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default"
+ confParam=[ "does.not.exist=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+action( type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+
+# We inject messages, even though we know this will not work. The reason
+# is that we want to ensure we do not get a segfault in such an error case
+injectmsg_kafkacat
+
+shutdown_when_empty
+wait_shutdown
+
+content_check "error setting custom configuration parameter 'does.not.exist=none'"
+delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+exit_test
diff --git a/tests/imkafka-config-err-ruleset.sh b/tests/imkafka-config-err-ruleset.sh
new file mode 100755
index 0000000..82c08f9
--- /dev/null
+++ b/tests/imkafka-config-err-ruleset.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+# added 2018-10-26 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+check_command_available kafkacat
+export KEEP_KAFKA_RUNNING="YES"
+
+export TESTMESSAGES=100000
+export RANDTOPIC=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+# Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only.
+#export EXTRA_EXITCHECK=dumpkafkalogs
+#export EXTRA_EXIT=kafka
+
+download_kafka
+stop_zookeeper
+stop_kafka
+start_zookeeper
+start_kafka
+
+generate_conf
+add_conf '
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+
+module(load="../plugins/imkafka/.libs/imkafka")
+/* Polls messages from kafka server!*/
+input( type="imkafka"
+ ruleset="does-not-exist"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default"
+ confParam=[ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if ($msg contains "msgnum:") then {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+} else {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME.errmsg'")
+}
+'
+startup
+
+injectmsg_kafkacat --wait 1 $TESTMESSAGES -d
+shutdown_when_empty
+wait_shutdown
+
+delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+stop_kafka
+stop_zookeeper
+
+seq_check 1 $TESTMESSAGES -d
+content_check "ruleset 'does-not-exist' not found" "$RSYSLOG_DYNNAME.errmsg"
+
+exit_test
diff --git a/tests/imkafka-hang-on-no-kafka.sh b/tests/imkafka-hang-on-no-kafka.sh
new file mode 100755
index 0000000..7e7d289
--- /dev/null
+++ b/tests/imkafka-hang-on-no-kafka.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# added 2018-10-22 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. $srcdir/diag.sh init
+export RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT=5000 # 5sec
+generate_conf
+add_conf '
+main_queue(queue.type="direct")
+
+module(load="../plugins/imkafka/.libs/imkafka")
+
+input( type="imkafka"
+ ruleset="kafka"
+ topic="irrelevant"
+ broker="localhost:29092"
+ consumergroup="default"
+ confParam=[ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true" ]
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+ruleset(name="kafka") {
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" )
+}
+
+action( type="omfile" file="'$RSYSLOG_OUT_LOG.syslog.log'" template="outfmt" )
+'
+
+export RSTB_DAEMONIZE="YES"
+startup
+shutdown_when_empty
+wait_shutdown
+# the main point is to see if we can terminate, so no further checks down here!
+exit_test
diff --git a/tests/imkafka-hang-other-action-on-no-kafka.sh b/tests/imkafka-hang-other-action-on-no-kafka.sh
new file mode 100755
index 0000000..fadcb67
--- /dev/null
+++ b/tests/imkafka-hang-other-action-on-no-kafka.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# added 2018-10-22 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT=5000 # 5sec
+generate_conf
+add_conf '
+main_queue(queue.type="direct")
+
+module(load="../plugins/imkafka/.libs/imkafka")
+
+input( type="imkafka"
+ ruleset="kafka"
+ topic="irrelevant"
+ broker="localhost:29092"
+ consumergroup="default"
+ confParam=[ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true" ]
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+ruleset(name="kafka") {
+ continue
+}
+
+if prifilt("local4.*") then
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" )
+else
+ action( type="omfile" file="'$RSYSLOG_OUT_LOG.syslog.log'" template="outfmt" )
+'
+
+export RSTB_DAEMONIZE="YES"
+startup
+injectmsg 0 10000
+shutdown_when_empty
+wait_shutdown
+seq_check 0 9999
+exit_test
diff --git a/tests/imkafka-vg.sh b/tests/imkafka-vg.sh
new file mode 100755
index 0000000..472a8ed
--- /dev/null
+++ b/tests/imkafka-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imkafka.sh
diff --git a/tests/imkafka.sh b/tests/imkafka.sh
new file mode 100755
index 0000000..052227c
--- /dev/null
+++ b/tests/imkafka.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# added 2018-08-29 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+check_command_available kafkacat
+export KEEP_KAFKA_RUNNING="YES"
+
+export TESTMESSAGES=100000
+export TESTMESSAGESFULL=$TESTMESSAGES
+# Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only.
+export EXTRA_EXITCHECK=dumpkafkalogs
+export EXTRA_EXIT=kafka
+
+export RANDTOPIC=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+
+download_kafka
+stop_zookeeper
+stop_kafka
+
+start_zookeeper
+start_kafka
+create_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+generate_conf
+add_conf '
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+
+module(load="../plugins/imkafka/.libs/imkafka")
+/* Polls messages from kafka server!*/
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if ($msg contains "msgnum:") then {
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" )
+}
+'
+startup
+injectmsg_kafkacat --wait 1 $TESTMESSAGESFULL -d
+shutdown_when_empty
+wait_shutdown
+
+delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+seq_check 1 $TESTMESSAGESFULL -d
+
+exit_test
diff --git a/tests/imkafka_multi_group.sh b/tests/imkafka_multi_group.sh
new file mode 100755
index 0000000..501aee7
--- /dev/null
+++ b/tests/imkafka_multi_group.sh
@@ -0,0 +1,112 @@
+#!/bin/bash
+# added 2018-08-29 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+check_command_available kafkacat
+export KEEP_KAFKA_RUNNING="YES"
+# False positive codefactor.io
+export RSYSLOG_OUT_LOG_1="${RSYSLOG_OUT_LOG:-default}.1"
+export RSYSLOG_OUT_LOG_2="${RSYSLOG_OUT_LOG:-default}.2"
+
+export TESTMESSAGES=100000
+# Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only.
+#export EXTRA_EXITCHECK=dumpkafkalogs
+#export EXTRA_EXIT=kafka
+
+download_kafka
+stop_zookeeper
+stop_kafka
+start_zookeeper
+start_kafka
+
+export RANDTOPIC=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+
+create_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+# Create FIRST rsyslog instance
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+
+module(load="../plugins/imkafka/.libs/imkafka")
+/* Polls messages from kafka server!*/
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="rsysloggroup"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if ($msg contains "msgnum:") then {
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" )
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG_1` template="outfmt" )
+}
+'
+echo Starting first rsyslog instance [imkafka]
+startup
+
+# Create SECOND rsyslog instance
+export RSYSLOG_DEBUGLOG="log2"
+generate_conf 2
+add_conf '
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+
+module(load="../plugins/imkafka/.libs/imkafka")
+/* Polls messages from kafka server!*/
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="rsysloggroup"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if ($msg contains "msgnum:") then {
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" )
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG_2` template="outfmt" )
+}
+' 2
+echo Starting second rsyslog instance [imkafka]
+startup 2
+
+
+TIMESTART=$(date +%s.%N)
+
+injectmsg_kafkacat
+# special case: number of test messages differs from file output
+wait_file_lines $RSYSLOG_OUT_LOG $((TESTMESSAGES)) ${RETRIES:-200}
+# Check that at least 25% messages are in both logfiles, otherwise load balancing hasn't worked
+wait_file_lines $RSYSLOG_OUT_LOG_1 $((TESTMESSAGES/4)) ${RETRIES:-200}
+wait_file_lines $RSYSLOG_OUT_LOG_2 $((TESTMESSAGES/4)) ${RETRIES:-200}
+
+echo Stopping first rsyslog instance [imkafka]
+shutdown_when_empty
+wait_shutdown
+
+echo Stopping second rsyslog instance [imkafka]
+shutdown_when_empty 2
+wait_shutdown 2
+
+TIMEEND=$(date +%s.%N)
+TIMEDIFF=$(echo "$TIMEEND - $TIMESTART" | bc)
+echo "*** imkafka time to process all data: $TIMEDIFF seconds!"
+
+delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+seq_check 1 $TESTMESSAGES -d
+
+exit_test
diff --git a/tests/imkafka_multi_single.sh b/tests/imkafka_multi_single.sh
new file mode 100755
index 0000000..d0127e0
--- /dev/null
+++ b/tests/imkafka_multi_single.sh
@@ -0,0 +1,151 @@
+#!/bin/bash
+# added 2018-08-29 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+check_command_available kafkacat
+export KEEP_KAFKA_RUNNING="YES"
+
+export TESTMESSAGES=100000
+# Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only.
+#export EXTRA_EXITCHECK=dumpkafkalogs
+#export EXTRA_EXIT=kafka
+
+download_kafka
+stop_zookeeper
+stop_kafka
+start_zookeeper
+start_kafka
+
+export RANDTOPIC=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+
+create_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+
+module(load="../plugins/imkafka/.libs/imkafka")
+/* Polls messages from kafka server!*/
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default1"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default2"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default3"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default4"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default5"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default6"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default7"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default8"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if ($msg contains "msgnum:") then {
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" )
+}
+'
+
+startup
+
+TIMESTART=$(date +%s.%N)
+
+injectmsg_kafkacat
+# special case: number of test messages differs from file output
+wait_file_lines $RSYSLOG_OUT_LOG $((TESTMESSAGES * 8)) ${RETRIES:-200}
+shutdown_when_empty
+wait_shutdown
+
+TIMEEND=$(date +%s.%N)
+TIMEDIFF=$(echo "$TIMEEND - $TIMESTART" | bc)
+echo "*** imkafka time to process all data: $TIMEDIFF seconds!"
+
+delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+seq_check 1 $TESTMESSAGES -d
+
+exit_test
diff --git a/tests/imklog_permitnonkernelfacility_root.sh b/tests/imklog_permitnonkernelfacility_root.sh
new file mode 100755
index 0000000..16e8b90
--- /dev/null
+++ b/tests/imklog_permitnonkernelfacility_root.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2017-07-18 by Pascal Withopf, released under ASL 2.0
+echo \[imklog_permitnonkernelfacility_root.sh\]: test parameter permitnonkernelfacility
+echo This test must be run as root with no other active syslogd
+if [ "$EUID" -ne 0 ]; then
+ exit 77 # Not root, skip this test
+fi
+service rsyslog stop
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imklog/.libs/imklog" permitnonkernelfacility="on")
+
+template(name="outfmt" type="string" string="%msg:57:16%: -%pri%-\n")
+
+:msg, contains, "msgnum" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+echo "<115>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1" > /dev/kmsg
+echo "<115>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1"
+sleep 2
+shutdown_when_empty
+wait_shutdown
+echo 'Mar 10 01:00:00 172.20.245.8 tag: msgnum:1: -115-' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+service rsyslog start
+exit_test
diff --git a/tests/immark-inputname.sh b/tests/immark-inputname.sh
new file mode 100755
index 0000000..90a5795
--- /dev/null
+++ b/tests/immark-inputname.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# add 2020-12-02 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/immark/.libs/immark" interval="1" use.syslogcall="off")
+if $inputname == "immark" then
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+printf 'sleeping a bit so we get mark messages...\n'
+sleep 3 # this should be good even on slow machines - we need just one
+shutdown_when_empty
+wait_shutdown
+content_check "rsyslogd: -- MARK --"
+
+exit_test
diff --git a/tests/immark-ruleset-custom-msg.sh b/tests/immark-ruleset-custom-msg.sh
new file mode 100755
index 0000000..eb8c116
--- /dev/null
+++ b/tests/immark-ruleset-custom-msg.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# very basic check for immark module - nevertheless, there is not
+# much more to test for...
+# add 2020-12-01 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/immark/.libs/immark" interval="1"
+ use.syslogcall="off" ruleset="rs" markmessagetext="My MARK Message")
+ruleset(name="rs") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+
+startup
+printf 'sleeping a bit so we get mark messages...\n'
+sleep 3 # this should be good even on slow machines - we need just one
+shutdown_when_empty
+wait_shutdown
+content_check "rsyslogd: My MARK Message"
+
+exit_test
diff --git a/tests/immark-ruleset.sh b/tests/immark-ruleset.sh
new file mode 100755
index 0000000..b2d3f57
--- /dev/null
+++ b/tests/immark-ruleset.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# very basic check for immark module - nevertheless, there is not
+# much more to test for...
+# add 2020-12-01 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/immark/.libs/immark" interval="1"
+ use.syslogcall="off" ruleset="rs")
+ruleset(name="rs") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+
+startup
+printf 'sleeping a bit so we get mark messages...\n'
+sleep 3 # this should be good even on slow machines - we need just one
+shutdown_when_empty
+wait_shutdown
+content_check "rsyslogd: -- MARK --"
+
+exit_test
diff --git a/tests/immark.sh b/tests/immark.sh
new file mode 100755
index 0000000..8e4be61
--- /dev/null
+++ b/tests/immark.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# very basic check for immark module - nevertheless, there is not
+# much more to test for...
+# add 2019-08-20 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/immark/.libs/immark" interval="1")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+printf 'sleeping a bit so we get mark messages...\n'
+sleep 3 # this should be good even on slow machines - we need just one
+shutdown_when_empty
+wait_shutdown
+content_check "rsyslogd: -- MARK --"
+
+exit_test
diff --git a/tests/improg-multiline-test.py b/tests/improg-multiline-test.py
new file mode 100755
index 0000000..c513cd7
--- /dev/null
+++ b/tests/improg-multiline-test.py
@@ -0,0 +1,6 @@
+# call this via "python[3] script name"
+import sys
+
+for _ in range(10):
+ mystr = 'multi-line-string\n'
+ sys.stdout.write(mystr)
diff --git a/tests/improg-simul.sh b/tests/improg-simul.sh
new file mode 100755
index 0000000..8d91203
--- /dev/null
+++ b/tests/improg-simul.sh
@@ -0,0 +1,70 @@
+#! /bin/bash
+# add 2019-04-04 by Philippe DUVEAU, released under ASL 2.0
+mysleep=./msleep
+ACK=0
+SLEEP=0
+DELAY=500
+NB=1
+MESSAGE="program datas"
+SIGNALED=0
+ERR=$0.stderr
+while getopts "cd:e:s:n:m:g" OPTION; do
+ case "${OPTION}" in
+ g)
+ SIGNALED=1
+ ;;
+ c)
+ ACK=1
+ ;;
+ d)
+ DELAY=${OPTARG}
+ ;;
+ e)
+ ERR=${OPTARG}
+ ;;
+ s)
+ SLEEP=${OPTARG}
+ ;;
+ n)
+ NB=${OPTARG}
+ ;;
+ m)
+ MESSAGE=${OPTARG}
+ ;;
+ *)
+ exit 0
+ esac
+done
+trap 'echo "SIGTERM Received" >> '$ERR';echo $0" SIGTERM Received" >&2;exit 0' 15
+if (( DELAY > 0 )); then $mysleep ${DELAY}; fi
+if [ ${ACK} == 1 ]; then
+ while [ "x$order" != "xSTART" ]; do
+ read -r order
+ echo $order' Received' >> $ERR
+ echo $0' '$order' Received' >&2
+ done
+ while [ "x$order" != "xSTOP" ]; do
+ if (( NB > 0 )); then
+ echo ${MESSAGE}
+ echo "Message sent" >&2
+ (( NB-- ))
+ fi
+ unset order
+ read -r order
+ echo $order' Received' >> $ERR
+ echo $0' '$order' Received' >&2
+ if (( SLEEP > 0 )); then $mysleep ${SLEEP}; fi
+ done
+else
+ while (( NB > 0 )); do
+ echo ${MESSAGE}
+ echo $0" Message sent" >&2
+ if (( SLEEP > 0 )); then $mysleep ${SLEEP}; fi
+ (( NB-- ))
+ done
+ if [ ${SIGNALED} == 1 ]; then
+ $mysleep 100000 &
+ wait
+ fi
+fi
+echo "Leaving improg_sender" >&2
diff --git a/tests/improg_errmsg_no_params-vg.sh b/tests/improg_errmsg_no_params-vg.sh
new file mode 100755
index 0000000..aa40b52
--- /dev/null
+++ b/tests/improg_errmsg_no_params-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/improg_errmsg_no_params.sh
diff --git a/tests/improg_errmsg_no_params.sh b/tests/improg_errmsg_no_params.sh
new file mode 100755
index 0000000..45a55ba
--- /dev/null
+++ b/tests/improg_errmsg_no_params.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/improg/.libs/improg")
+
+input(type="improg")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter 'binary' required but not specified"
+
+exit_test
diff --git a/tests/improg_prog_confirm.sh b/tests/improg_prog_confirm.sh
new file mode 100755
index 0000000..e0af636
--- /dev/null
+++ b/tests/improg_prog_confirm.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# add 2019-04-04 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/improg/.libs/improg")
+input(type="improg" tag="tag" ruleset="ruleset"
+ binary="'${srcdir:=.}'/improg-simul.sh -e '$RSYSLOG_DYNNAME'.stderr -c -n 1"
+ confirmmessages="on" signalonclose="off" killunresponsive="on"
+ )
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "program data"
+if [ ! -e $RSYSLOG_DYNNAME.stderr ]; then
+ echo $RSYSLOG_DYNNAME'.stderr missing'
+ error_exit 1
+fi
+export EXPECTED='START Received
+ACK Received
+STOP Received'
+cmp_exact $RSYSLOG_DYNNAME.stderr
+exit_test
diff --git a/tests/improg_prog_confirm_killonclose.sh b/tests/improg_prog_confirm_killonclose.sh
new file mode 100755
index 0000000..b9a75ce
--- /dev/null
+++ b/tests/improg_prog_confirm_killonclose.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# add 2019-04-04 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/improg/.libs/improg")
+input(type="improg" tag="tag" ruleset="ruleset"
+ binary="'${srcdir:=.}'/improg-simul.sh -e '$RSYSLOG_DYNNAME'.stderr -c -n 1 -g"
+ confirmmessages="on" signalonclose="on" killunresponsive="on"
+ )
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "program data"
+if [ ! -e $RSYSLOG_DYNNAME.stderr ]; then
+ echo $RSYSLOG_DYNNAME'.stderr missing'
+ error_exit 1
+fi
+export EXPECTED='START Received
+ACK Received
+SIGTERM Received'
+cmp_exact $RSYSLOG_DYNNAME.stderr
+
+exit_test
diff --git a/tests/improg_prog_killonclose.sh b/tests/improg_prog_killonclose.sh
new file mode 100755
index 0000000..42d9f12
--- /dev/null
+++ b/tests/improg_prog_killonclose.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# add 2019-04-04 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/improg/.libs/improg")
+input(type="improg" tag="tag" ruleset="ruleset"
+ binary="'${srcdir:=.}'/improg-simul.sh -e '$RSYSLOG_DYNNAME'.stderr -n 1 -g"
+ confirmmessages="off" signalonclose="on" killunresponsive="on"
+ )
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "program data"
+if [ ! -e $RSYSLOG_DYNNAME.stderr ]; then
+ echo $RSYSLOG_DYNNAME'.stderr missing'
+ error_exit 1
+fi
+export EXPECTED='SIGTERM Received'
+cmp_exact $RSYSLOG_DYNNAME.stderr
+exit_test
diff --git a/tests/improg_prog_simple-vg.sh b/tests/improg_prog_simple-vg.sh
new file mode 100755
index 0000000..1a1f426
--- /dev/null
+++ b/tests/improg_prog_simple-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/improg_prog_simple.sh
diff --git a/tests/improg_prog_simple.sh b/tests/improg_prog_simple.sh
new file mode 100755
index 0000000..af4d383
--- /dev/null
+++ b/tests/improg_prog_simple.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# add 2019-04-04 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/improg/.libs/improg")
+input(type="improg" tag="tag" ruleset="ruleset"
+ binary="'${srcdir:=.}'/improg-simul.sh -e '$RSYSLOG_DYNNAME'.stderr"
+ confirmmessages="off" closetimeout="2000"
+ )
+ruleset(name="ruleset") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "program data"
+if [ -e $RSYSLOG_DYNNAME.stderr ]; then
+ echo 'improg-simul stderr:'
+ cat $RSYSLOG_DYNNAME.stderr
+ error_exit 1
+fi
+exit_test
diff --git a/tests/improg_simple_multi.sh b/tests/improg_simple_multi.sh
new file mode 100755
index 0000000..babcb9b
--- /dev/null
+++ b/tests/improg_simple_multi.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+#
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/improg/.libs/improg")
+template(name="outfmt" type="string" string="#%msg%#\n")
+input(type="improg" tag="tag" ruleset="ruleset"
+ binary="'$PYTHON' '$srcdir'/improg-multiline-test.py"
+ confirmmessages="off" closetimeout="2000"
+ )
+ruleset(name="ruleset") {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+startup
+shutdown_when_empty
+wait_shutdown
+NUM_ITEMS=10
+echo "expected: $NUM_EXPECTED"
+echo "file: $RSYSLOG_OUT_LOG"
+content_check_with_count "#multi-line-string#" $NUM_EXPECTED $NUM_ITEMS
+exit_test
diff --git a/tests/impstats-hup.sh b/tests/impstats-hup.sh
new file mode 100755
index 0000000..9f16371
--- /dev/null
+++ b/tests/impstats-hup.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# test if HUP works for impstats
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/impstats/.libs/impstats"
+ log.file=`echo $RSYSLOG_OUT_LOG`
+ interval="1" ruleset="stats")
+
+ruleset(name="stats") {
+ stop # nothing to do here
+}
+'
+startup
+./msleep 2000
+mv $RSYSLOG_OUT_LOG ${RSYSLOG2_OUT_LOG}
+issue_HUP
+./msleep 2000
+shutdown_when_empty
+wait_shutdown
+echo checking pre-HUP file
+content_check 'global: origin=dynstats' ${RSYSLOG2_OUT_LOG}
+echo checking post-HUP file
+content_check 'global: origin=dynstats' $RSYSLOG_OUT_LOG
+exit_test
diff --git a/tests/imptcp-NUL-rawmsg.sh b/tests/imptcp-NUL-rawmsg.sh
new file mode 100755
index 0000000..d843e5c
--- /dev/null
+++ b/tests/imptcp-NUL-rawmsg.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# addd 2016-05-13 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%rawmsg%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+echo '<167>Mar 6 16:57:54 172.20.245.8 test: msgnum:0 X test message
+<167>Mar 6 16:57:54 172.20.245.8 Xtest: msgnum:1 test message' | tr X '\000' > $RSYSLOG_DYNNAME.input
+tcpflood -B -I $RSYSLOG_DYNNAME.input
+shutdown_when_empty
+wait_shutdown
+echo '<167>Mar 6 16:57:54 172.20.245.8 test: msgnum:0 #000 test message
+<167>Mar 6 16:57:54 172.20.245.8 #000test: msgnum:1 test message' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid output generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi;
+exit_test
diff --git a/tests/imptcp-NUL.sh b/tests/imptcp-NUL.sh
new file mode 100755
index 0000000..935e679
--- /dev/null
+++ b/tests/imptcp-NUL.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# addd 2016-05-13 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+echo '<167>Mar 6 16:57:54 172.20.245.8 test: msgnum:0 X test message
+<167>Mar 6 16:57:54 172.20.245.8 Xtest: msgnum:1 test message' | tr X '\000' > $RSYSLOG_DYNNAME.input
+tcpflood -B -I $RSYSLOG_DYNNAME.input
+shutdown_when_empty
+wait_shutdown
+seq_check 0 1
+exit_test
diff --git a/tests/imptcp-basic-hup.sh b/tests/imptcp-basic-hup.sh
new file mode 100755
index 0000000..a58888f
--- /dev/null
+++ b/tests/imptcp-basic-hup.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# added 2019-07-30 by RGerhards, released under ASL 2.0
+export NUMMESSAGES=4000 # MUST be an even number!
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2))
+issue_HUP
+tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) -i$((NUMMESSAGES / 2))
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imptcp-connection-msg-disabled.sh b/tests/imptcp-connection-msg-disabled.sh
new file mode 100755
index 0000000..1cf1139
--- /dev/null
+++ b/tests/imptcp-connection-msg-disabled.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# addd 2017-03-31 by Pascal Withopf, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+:msg, contains, "msgnum:" {
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -m1 -M"\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\""
+shutdown_when_empty
+wait_shutdown
+
+grep "imptcp: connection established" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -eq 0 ]; then
+ echo
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+grep "imptcp: session on socket.* closed" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -eq 0 ]; then
+ echo
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imptcp-connection-msg-received.sh b/tests/imptcp-connection-msg-received.sh
new file mode 100755
index 0000000..0b8ca3d
--- /dev/null
+++ b/tests/imptcp-connection-msg-received.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# addd 2017-03-31 by Pascal Withopf, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ notifyonconnectionclose="on" notifyonconnectionopen="on")
+
+:msg, contains, "msgnum:" {
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -m1 -M"\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\""
+shutdown_when_empty
+wait_shutdown
+
+grep "imptcp: connection established" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+grep "imptcp: session on socket.* closed" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imptcp-discard-truncated-msg.sh b/tests/imptcp-discard-truncated-msg.sh
new file mode 100755
index 0000000..a734b4b
--- /dev/null
+++ b/tests/imptcp-discard-truncated-msg.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# addd 2016-05-13 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 128
+global(processInternalMessages="on")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ ruleset="ruleset1" discardTruncatedMsg="on")
+
+template(name="outfmt" type="string" string="%rawmsg%\n")
+ruleset(name="ruleset1") {
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way to long message that has abcdefghijklmnopqrstuvwxyz test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16\""
+tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way to long message\""
+tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way to long message that has abcdefghijklmnopqrstuvwxyz test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16\""
+tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way to long message\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='<120> 2011-03-01T11:22:12Z host tag: this is a way to long message that has abcdefghijklmnopqrstuvwxyz test1 test2 test3 test4 t
+<120> 2011-03-01T11:22:12Z host tag: this is a way to long message
+<120> 2011-03-01T11:22:12Z host tag: this is a way to long message that has abcdefghijklmnopqrstuvwxyz test1 test2 test3 test4 t
+<120> 2011-03-01T11:22:12Z host tag: this is a way to long message'
+cmp_exact
+exit_test
diff --git a/tests/imptcp-maxFrameSize-parameter.sh b/tests/imptcp-maxFrameSize-parameter.sh
new file mode 100755
index 0000000..0b9b376
--- /dev/null
+++ b/tests/imptcp-maxFrameSize-parameter.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# addd 2017-03-01 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 12800
+global(processInternalMessages="on")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" maxframesize="100")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+
+'
+startup
+tcpflood -m1 -M "\"10005 <120> 2011-03-01T11:22:12Z host tag: this is a way too long message\""
+shutdown_when_empty
+wait_shutdown
+
+grep "Framing Error.*change to octet stuffing" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message from imptcp truncation not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imptcp-msg-truncation-on-number.sh b/tests/imptcp-msg-truncation-on-number.sh
new file mode 100755
index 0000000..fa7f439
--- /dev/null
+++ b/tests/imptcp-msg-truncation-on-number.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# addd 2017-03-01 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 128
+global(processInternalMessages="on"
+ oversizemsg.input.mode="accept")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+
+'
+startup
+tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way too long message that has to be truncatedtest1 test2 test3 test4 test5 ab
+9876543210 cdefghijklmn test8 test9 test10 test11 test12 test13 test14 test15 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk tag: testtestetstetstetstetstetsstetstetsytetestetste\""
+shutdown_when_empty
+wait_shutdown
+
+grep "Framing Error" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message from imptcp truncation not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+grep " 9876543210cdefghijklmn test8 test9 test10 test11 test12 test13 test14 test15 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk tag: testtestets" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message from imptcp truncation not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imptcp-msg-truncation-on-number2.sh b/tests/imptcp-msg-truncation-on-number2.sh
new file mode 100755
index 0000000..36009c4
--- /dev/null
+++ b/tests/imptcp-msg-truncation-on-number2.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# addd 2017-03-01 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 128
+global(processInternalMessages="on"
+ oversizemsg.input.mode="accept")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="templ1" type="string" string="%rawmsg%\n")
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="templ1")
+}
+
+'
+startup
+tcpflood -m2 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"214000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"214000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"2000000010 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"4000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"0 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+shutdown_when_empty
+wait_shutdown
+
+echo '<120> 2011-03-01T11:22:12Z host msgnum:1
+<120> 2011-03-01T11:22:12Z host msgnum:1
+214000000000<120> 2011-03-01T11:22:12Z host msgnum:1
+<120> 2011-03-01T11:22:12Z host msgnum:1
+214000000000<120> 2011-03-01T11:22:12Z host msgnum:1
+<120> 2011-03-01T11:22:12Z host msgnum:1
+2000000010<120> 2011-03-01T11:22:12Z host msgnum:1
+4000000000<120> 2011-03-01T11:22:12Z host msgnum:1
+<120> 2011-03-01T11:22:12Z host msgnum:1' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imptcp-octet-framing-too-long-vg.sh b/tests/imptcp-octet-framing-too-long-vg.sh
new file mode 100755
index 0000000..d5b2c9a
--- /dev/null
+++ b/tests/imptcp-octet-framing-too-long-vg.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# added 2022-04-25 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 128
+global(processInternalMessages="on"
+ oversizemsg.input.mode="accept")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup_vg
+echo "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000 <120> 2011-03-01T11:22:12Z host tag: this is a way too long message that has to be truncatedtest1 test2 test3 test4 test5 ab" > $RSYSLOG_DYNNAME.inputfile
+tcpflood -I $RSYSLOG_DYNNAME.inputfile
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+# the prime objective is to see if valgrind check is ok, but we also do a quick content check (just in case)
+content_check "received oversize message from peer"
+exit_test
diff --git a/tests/imptcp-oversize-message-display.sh b/tests/imptcp-oversize-message-display.sh
new file mode 100755
index 0000000..4fae531
--- /dev/null
+++ b/tests/imptcp-oversize-message-display.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# addd 2017-03-01 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 128
+global(processInternalMessages="on" oversizemsg.input.mode="accept")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+
+'
+startup
+tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way too long message that has to be truncatedtest1 test2 test3 test4 test5 abcdefghijklmn test8 test9 test10 test11 test12 test13 test14 test15 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk tag: testtestetstetstetstetstetsstetstetsytetestetste\""
+shutdown_when_empty
+wait_shutdown
+
+if ! grep "imptcp: message received.*150 byte larger.*will be split.*\"ghijkl" $RSYSLOG_OUT_LOG > /dev/null
+then
+ echo
+ echo "FAIL: expected error message from imptcp truncation not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+if ! grep "imptcp: message received.*22 byte larger.*will be split.*\"sstets" $RSYSLOG_OUT_LOG > /dev/null
+then
+ echo
+ echo "FAIL: expected error message from imptcp truncation not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+if grep "imptcp: message received.*21 byte larger" $RSYSLOG_OUT_LOG > /dev/null
+then
+ echo
+ echo "FAIL: UNEXPECTED error message from imptcp truncation found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imptcp_addtlframedelim.sh b/tests/imptcp_addtlframedelim.sh
new file mode 100755
index 0000000..3ae32e0
--- /dev/null
+++ b/tests/imptcp_addtlframedelim.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# added 2010-08-11 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=20000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ addtlFrameDelimiter="0")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+local0.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+tcpflood -m$NUMMESSAGES -F0 -P129
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imptcp_conndrop-vg.sh b/tests/imptcp_conndrop-vg.sh
new file mode 100755
index 0000000..7852fb1
--- /dev/null
+++ b/tests/imptcp_conndrop-vg.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export TB_TEST_MAX_RUNTIME=1200 # connection drops are very slow...
+export NUMMESSAGES=10000 # even if it is slow, we use a large number to be
+ # sure to have sufficient connection drops - but as low as possible!
+source ${srcdir:-.}/imptcp_conndrop.sh
diff --git a/tests/imptcp_conndrop.sh b/tests/imptcp_conndrop.sh
new file mode 100755
index 0000000..8c01806
--- /dev/null
+++ b/tests/imptcp_conndrop.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Test imptcp with many dropping connections
+# added 2010-08-10 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=${NUMMESSAGES:-50000} # permit valgrind test to override value
+export TB_TEST_MAX_RUNTIME=${TB_TEST_MAX_RUNTIME:-700} # connection drops are very slow...
+generate_conf
+add_conf '
+$MaxMessageSize 10k
+
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n"
+template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'")
+$OMFileFlushInterval 2
+$OMFileIOBufferSize 256k
+local0.* ?dynfile;outfmt
+'
+startup
+# 100 byte messages to gain more practical data use
+tcpflood -c20 -m$NUMMESSAGES -r -d100 -P129 -D
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+export SEQ_CHECK_OPTIONS=-E
+seq_check
+exit_test
diff --git a/tests/imptcp_framing_regex-oversize.sh b/tests/imptcp_framing_regex-oversize.sh
new file mode 100755
index 0000000..c5b74dd
--- /dev/null
+++ b/tests/imptcp_framing_regex-oversize.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$EscapeControlCharactersOnReceive off
+global(maxMessageSize="256")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ ruleset="remote"
+ framing.delimiter.regex="^<[0-9]{2}>(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)")
+
+template(name="outfmt" type="string" string="NEWMSG: %rawmsg%\n")
+ruleset(name="remote") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -B -I ${srcdir}/testsuites/imptcp_framing_regex-oversize.testdata
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+export EXPECTED='NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag test1
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag test xml-ish
+<test/>
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag test2
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag multi
+line1
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag multi
+ 1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ 2-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ 3-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+NEWMSG: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ 7-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ 8-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+END
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag test3
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag multi
+line3
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag test4'
+cmp_exact
+content_check-regex "assuming end of frame" ${RSYSLOG2_OUT_LOG}
+content_check-regex "message too long" ${RSYSLOG2_OUT_LOG}
+exit_test
diff --git a/tests/imptcp_framing_regex.sh b/tests/imptcp_framing_regex.sh
new file mode 100755
index 0000000..f2eacd3
--- /dev/null
+++ b/tests/imptcp_framing_regex.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$EscapeControlCharactersOnReceive off
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ ruleset="remote"
+ framing.delimiter.regex="^<[0-9]{2}>(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)")
+
+template(name="outfmt" type="string" string="NEWMSG: %rawmsg%\n")
+ruleset(name="remote") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -B -I ${srcdir}/testsuites/imptcp_framing_regex.testdata
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag test1
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag test xml-ish
+<test/>
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag test2
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag multi
+line1
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag multi
+ l
+ i
+ n
+
+e2
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag test3
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag multi
+line3
+NEWMSG: <33>Mar 1 01:00:00 172.20.245.8 tag test4'
+cmp_exact
+exit_test
diff --git a/tests/imptcp_large.sh b/tests/imptcp_large.sh
new file mode 100755
index 0000000..f5664a7
--- /dev/null
+++ b/tests/imptcp_large.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Test imptcp with large messages
+# added 2010-08-10 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=20000
+generate_conf
+add_conf '
+global(maxMessageSize="10k")
+template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+# send messages of 10.000bytes plus header max, randomized
+tcpflood -c5 -m$NUMMESSAGES -r -d10000
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check 0 $((NUMMESSAGES - 1)) -E
+exit_test
diff --git a/tests/imptcp_maxsessions.sh b/tests/imptcp_maxsessions.sh
new file mode 100755
index 0000000..0428414
--- /dev/null
+++ b/tests/imptcp_maxsessions.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# Test imtcp with many dropping connections
+# added 2010-08-10 by Rgerhards
+#
+# This file is part of the rsyslog project, released under GPLv3
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test currently does not work on FreeBSD"
+export NUMMESSAGES=500
+
+MAXSESSIONS=10
+CONNECTIONS=20
+EXPECTED_DROPS=$((CONNECTIONS - MAXSESSIONS))
+
+EXPECTED_STR='too many tcp sessions - dropping incoming request'
+wait_too_many_sessions()
+{
+ test "$(grep "$EXPECTED_STR" "$RSYSLOG_OUT_LOG" | wc -l)" = "$EXPECTED_DROPS"
+}
+
+export QUEUE_EMPTY_CHECK_FUNC=wait_too_many_sessions
+generate_conf
+add_conf '
+$MaxMessageSize 10k
+
+module(load="../plugins/imptcp/.libs/imptcp" maxsessions="'$MAXSESSIONS'")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+
+$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n"
+$OMFileFlushInterval 2
+$OMFileIOBufferSize 256k
+'
+startup
+
+echo "INFO: RSYSLOG_OUT_LOG: $RSYSLOG_OUT_LOG"
+
+echo "About to run tcpflood"
+tcpflood -c$CONNECTIONS -m$NUMMESSAGES -r -d100 -P129 -A
+echo "-------> NOTE: CLOSED REMOTELY messages are expected and OK! <-------"
+echo "done run tcpflood"
+shutdown_when_empty
+wait_shutdown
+
+content_count_check "$EXPECTED_STR" $EXPECTED_DROPS
+echo "Got expected drops: $EXPECTED_DROPS, looks good!"
+
+exit_test
diff --git a/tests/imptcp_multi_line.sh b/tests/imptcp_multi_line.sh
new file mode 100755
index 0000000..f21fae8
--- /dev/null
+++ b/tests/imptcp_multi_line.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="remote" multiline="on")
+
+template(name="outfmt" type="string" string="NEWMSG: %rawmsg%\n")
+ruleset(name="remote") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -B -I ${srcdir}/testsuites/imptcp_multi_line.testdata
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+export EXPECTED='NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag test1
+NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag test2
+NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag multi#012line1
+NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag multi#012l#012i#012n#012#012e2
+NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag test3
+NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag multi#012line3
+NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag test4
+NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag test end'
+cmp_exact
+exit_test
diff --git a/tests/imptcp_no_octet_counted.sh b/tests/imptcp_no_octet_counted.sh
new file mode 100755
index 0000000..e732ed3
--- /dev/null
+++ b/tests/imptcp_no_octet_counted.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+echo ====================================================================================
+echo TEST: \[imptcp_no_octet_counted.sh\]: test imptcp with octet counted framing disabled
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="remote" supportOctetCountedFraming="off")
+
+template(name="outfmt" type="string" string="%rawmsg%\n")
+ruleset(name="remote") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -B -I ${srcdir}/testsuites/no_octet_counted.testdata
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+seq_check 0 19
+exit_test
diff --git a/tests/imptcp_nonProcessingPoller.sh b/tests/imptcp_nonProcessingPoller.sh
new file mode 100755
index 0000000..84c05ab
--- /dev/null
+++ b/tests/imptcp_nonProcessingPoller.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# Test imptcp with poller not processing any messages
+# added 2015-10-16 by singh.janmejay
+# This file is part of the rsyslog project, released under GPLv3
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=20000
+generate_conf
+add_conf '
+$MaxMessageSize 10k
+template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+
+module(load="../plugins/imptcp/.libs/imptcp" threads="32" processOnPoller="off")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+if (prifilt("local0.*")) then {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+startup
+tcpflood -c1 -m $NUMMESSAGES -r -d10000 -P129 -O
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check 0 $((NUMMESSAGES - 1)) -E
+exit_test
diff --git a/tests/imptcp_spframingfix.sh b/tests/imptcp_spframingfix.sh
new file mode 100755
index 0000000..ada8e3d
--- /dev/null
+++ b/tests/imptcp_spframingfix.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ====================================================================================
+echo TEST: \[imptcp_spframingfix.sh\]: test imptcp in regard to Cisco ASA framing fix
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="remote" framingfix.cisco.asa="on")
+
+template(name="outfmt" type="string" string="%rawmsg:6:7%\n")
+ruleset(name="remote") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -B -I ${srcdir}/testsuites/spframingfix.testdata
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+seq_check 0 19
+exit_test
diff --git a/tests/imptcp_veryLargeOctateCountedMessages.sh b/tests/imptcp_veryLargeOctateCountedMessages.sh
new file mode 100755
index 0000000..21c1fb9
--- /dev/null
+++ b/tests/imptcp_veryLargeOctateCountedMessages.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# Test imptcp with poller not processing any messages
+# test imptcp with very large messages while poller driven processing is disabled
+# added 2015-10-17 by singh.janmejay
+# This file is part of the rsyslog project, released under GPLv3
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=20000
+generate_conf
+add_conf '$MaxMessageSize 10k
+template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+
+module(load="../plugins/imptcp/.libs/imptcp" threads="32" processOnPoller="off")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+if (prifilt("local0.*")) then {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+export RS_REDIR="2>/dev/null"
+startup
+tcpflood -c1 -m$NUMMESSAGES -r -d100000 -P129 -O
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check 0 $((NUMMESSAGES - 1)) -E -T
+exit_test
diff --git a/tests/imrelp-basic-hup.sh b/tests/imrelp-basic-hup.sh
new file mode 100755
index 0000000..d67f1ca
--- /dev/null
+++ b/tests/imrelp-basic-hup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2019-07-30 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=4000 # MUST be an even number!
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+input(type="imrelp" port="'$TCPFLOOD_PORT'")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -Trelp-plain -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2))
+issue_HUP
+tcpflood -Trelp-plain -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) -i$((NUMMESSAGES / 2))
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imrelp-basic-oldstyle.sh b/tests/imrelp-basic-oldstyle.sh
new file mode 100755
index 0000000..4f5ea16
--- /dev/null
+++ b/tests/imrelp-basic-oldstyle.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# addd 2018-10-09 by Alorbach, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+
+$ModLoad ../plugins/imrelp/.libs/imrelp # Old Style module loading
+$inputrelpserverrun '$TCPFLOOD_PORT'
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m10000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 9999
+exit_test
diff --git a/tests/imrelp-basic-vg.sh b/tests/imrelp-basic-vg.sh
new file mode 100755
index 0000000..8957601
--- /dev/null
+++ b/tests/imrelp-basic-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imrelp-basic.sh
diff --git a/tests/imrelp-basic.sh b/tests/imrelp-basic.sh
new file mode 100755
index 0000000..efc93d5
--- /dev/null
+++ b/tests/imrelp-basic.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# addd 2016-05-13 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10000 # MUST be an even number!
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+input(type="imrelp" port="'$TCPFLOOD_PORT'")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -Trelp-plain -p$TCPFLOOD_PORT -m$NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imrelp-bigmessage.sh b/tests/imrelp-bigmessage.sh
new file mode 100755
index 0000000..39ca4c7
--- /dev/null
+++ b/tests/imrelp-bigmessage.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+# add 2020-02-11 by alorbach, released under ASL 2.0
+TEST_BYTES_EXPECTED=262152
+
+. ${srcdir:=.}/diag.sh init
+./have_relpSrvSetOversizeMode
+if [ $? -eq 1 ]; then
+ echo "imrelp parameter oversizeMode not available. Test stopped"
+ exit 77
+fi;
+generate_conf
+add_conf '
+global(
+ workDirectory="'$RSYSLOG_DYNNAME.spool'"
+ maxMessageSize="256k"
+)
+module(load="../plugins/imrelp/.libs/imrelp")
+input(
+ type="imrelp"
+ name="imrelp"
+ port="'$TCPFLOOD_PORT'"
+ ruleset="print"
+ MaxDataSize="260k"
+)
+#input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="200" oversizeMode="accept")
+
+template(name="print_message" type="list"){
+ constant(value="inputname: ")
+ property(name="inputname")
+ constant(value=", strlen: ")
+ property(name="$!strlen")
+ constant(value=", message: ")
+ property(name="msg")
+ constant(value="\n")
+}
+ruleset(name="print") {
+ set $!strlen = strlen($msg);
+ action(
+ type="omfile" template="print_message"
+ file=`echo $RSYSLOG_OUT_LOG`
+ )
+# action(
+# type="omstdout"
+# template="print_message"
+# )
+}
+
+#template(name="outfmt" type="string" string="%msg%\n")
+#:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+# file=`echo $RSYSLOG_OUT_LOG`)
+
+'
+startup
+tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m1 -d 262144
+# would also works well:
+# tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -R 1 -I "imrelp-bigmessage.log"
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+# We need the ^-sign to symbolize the beginning and the $-sign to symbolize the end
+# because otherwise we won't know if it was truncated at the right length.
+
+content_check "inputname: imrelp, strlen: 262107, message: msgnum:00000000:262144:"
+count=$(wc -c < $RSYSLOG_OUT_LOG)
+if [ $count -lt $TEST_BYTES_EXPECTED ]; then
+ echo
+ echo "FAIL: expected bytes count $count did not match $TEST_BYTES_EXPECTED. "
+ echo
+ echo "First 100 bytes of $RSYSLOG_OUT_LOG are: "
+ head -c 100 $RSYSLOG_OUT_LOG
+ echo
+ echo "Last 100 bytes of $RSYSLOG_OUT_LOG are: "
+ tail -c 100 $RSYSLOG_OUT_LOG
+ error_exit 1
+else
+ echo "Found $count bytes in $RSYSLOG_OUT_LOG"
+fi
+
+exit_test
diff --git a/tests/imrelp-invld-tlslib.sh b/tests/imrelp-invld-tlslib.sh
new file mode 100755
index 0000000..7c242cf
--- /dev/null
+++ b/tests/imrelp-invld-tlslib.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# see that we can an error message if wrong tls lib is selected
+# addd 2019-02-09 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+require_relpEngineSetTLSLibByName
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp" tls.tlslib="invalid-tlslib-name")
+input(type="imrelp" port="'$TCPFLOOD_PORT'") #prevent extra config error, not really needed
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+content_check --regex "invalid-tlslib-name.*not accepted"
+exit_test
diff --git a/tests/imrelp-long-msg.sh b/tests/imrelp-long-msg.sh
new file mode 100755
index 0000000..b377c18
--- /dev/null
+++ b/tests/imrelp-long-msg.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# adddd 2018-04-16 by PascalWithopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(maxMessageSize="214800")
+module(load="../plugins/imrelp/.libs/imrelp")
+input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="214800")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m2 -d 204800
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 1
+exit_test
diff --git a/tests/imrelp-manyconn-vg.sh b/tests/imrelp-manyconn-vg.sh
new file mode 100755
index 0000000..ef5c702
--- /dev/null
+++ b/tests/imrelp-manyconn-vg.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+if [ "$CI_ENV" == "Centos7VM" ]; then
+ # we give up, for some reason we see errors in this env but in no other Centos 7 env
+ # this is a hack for rsyslog official CI - sorry for that -- rgerhards, 2019-01-24
+ echo "SKIP test, as for some reason it does not work here - this should be investigated"
+ exit 77
+fi
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/imrelp-manyconn.sh
diff --git a/tests/imrelp-manyconn.sh b/tests/imrelp-manyconn.sh
new file mode 100755
index 0000000..a5d939a
--- /dev/null
+++ b/tests/imrelp-manyconn.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# adddd 2016-06-08 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test currently does not work on FreeBSD"
+export NUMMESSAGES=100000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+input(type="imrelp" port="'$TCPFLOOD_PORT'")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+tcpflood -Trelp-plain -c-2000 -p$TCPFLOOD_PORT -m$NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imrelp-maxDataSize-error.sh b/tests/imrelp-maxDataSize-error.sh
new file mode 100755
index 0000000..a64ceab
--- /dev/null
+++ b/tests/imrelp-maxDataSize-error.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2018-04-26 by Pascal Withopf, released under ASL 2.0
+echo [imrelp-maxDataSize-error.sh]
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+
+global(
+ maxMessageSize="300"
+)
+
+input(type="imrelp" port="'$TCPFLOOD_PORT'" maxDataSize="250")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+./msleep 2000
+
+shutdown_when_empty
+wait_shutdown
+
+grep "error: maxDataSize.*smaller than global parameter maxMessageSize" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imrelp-oversizeMode-accept.sh b/tests/imrelp-oversizeMode-accept.sh
new file mode 100755
index 0000000..c743f9e
--- /dev/null
+++ b/tests/imrelp-oversizeMode-accept.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# add 2018-04-25 by PascalWithopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+./have_relpSrvSetOversizeMode
+if [ $? -eq 1 ]; then
+ echo "imrelp parameter oversizeMode not available. Test stopped"
+ exit 77
+fi;
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="200" oversizeMode="accept")
+
+template(name="outfmt" type="string" string="%msg%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m1 -d 240
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+# We need the ^-sign to symbolize the beginning and the $-sign to symbolize the end
+# because otherwise we won't know if it was truncated at the right length.
+grep "^ msgnum:00000000:240:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imrelp-oversizeMode-truncate.sh b/tests/imrelp-oversizeMode-truncate.sh
new file mode 100755
index 0000000..b23a775
--- /dev/null
+++ b/tests/imrelp-oversizeMode-truncate.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# add 2018-04-19 by PascalWithopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+./have_relpSrvSetOversizeMode
+if [ $? -eq 1 ]; then
+ echo "imrelp parameter oversizeMode not available. Test stopped"
+ exit 77
+fi;
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+global(maxMessageSize="150" oversizemsg.input.mode="accept")
+
+
+input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="200" oversizeMode="truncate")
+
+template(name="outfmt" type="string" string="%msg%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m1 -d 240
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+# We need the ^-sign to symbolize the beginning and the $-sign to symbolize the end
+# because otherwise we won't know if it was truncated at the right length.
+grep "^ msgnum:00000000:240:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imrelp-sessionbreak-vg.sh b/tests/imrelp-sessionbreak-vg.sh
new file mode 100755
index 0000000..076c771
--- /dev/null
+++ b/tests/imrelp-sessionbreak-vg.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+# added 2020-04-10 by alorbach, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000000
+export USE_VALGRIND="YES"
+# TODO remote leak check skip and fix memory leaks caused by session break
+export RS_TESTBENCH_LEAK_CHECK=no
+
+mkdir $RSYSLOG_DYNNAME.workdir
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+
+global(
+ workDirectory="'$RSYSLOG_DYNNAME.workdir'"
+ maxMessageSize="256k"
+)
+main_queue(queue.type="Direct")
+
+$LocalHostName test
+$AbortOnUncleanConfig on
+$PreserveFQDN on
+
+input( type="imrelp"
+ name="imrelp"
+ port="'$TCPFLOOD_PORT'"
+ ruleset="spool"
+ MaxDataSize="256k"
+ KeepAlive="on"
+)
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+ruleset(name="spool" queue.type="direct") {
+ if $msg contains "msgnum:" then {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+ }
+}
+'
+startup
+# How many tcpfloods we run at the same tiem
+for ((i=1;i<=5;i++)); do
+ # How many times tcpflood runs in each threads
+ ./tcpflood -Trelp-plain -p$TCPFLOOD_PORT -m$NUMMESSAGES -s &
+ tcpflood_pid=$!
+
+ echo "started tcpflood instance $i (PID $tcpflood_pid)"
+
+ # Give it time to actually connect
+ ./msleep 500;
+
+ kill -9 $tcpflood_pid # >/dev/null 2>&1;
+ echo "killed tcpflood instance $i (PID $tcpflood_pid)"
+done;
+
+wait_queueempty
+
+netstatresult=$(netstat --all --program 2>&1 | grep "ESTABLISHED" | grep $(cat $RSYSLOG_PIDBASE.pid) | grep $TCPFLOOD_PORT)
+openfd=$(ls -l "/proc/$(cat $RSYSLOG_PIDBASE$1.pid)/fd" | wc -l)
+
+shutdown_when_empty
+wait_shutdown
+
+if [[ "$netstatresult" == "" ]]
+then
+ echo "OK!"
+else
+ echo "STILL OPENED Connections: "
+ echo $netstatresult
+ echo "Open files at the end: "
+ echo $openfd
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imrelp-tls-cfgcmd.sh b/tests/imrelp-tls-cfgcmd.sh
new file mode 100755
index 0000000..6d03c2b
--- /dev/null
+++ b/tests/imrelp-tls-cfgcmd.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# addd 2019-11-14 by alorbach, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+require_relpEngineSetTLSLibByName
+export NUMMESSAGES=1000
+export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+module( load="../plugins/imrelp/.libs/imrelp"
+ tls.tlslib="openssl")
+input(type="imrelp" port="'$TCPFLOOD_PORT'" tls="on"
+ tls.cacert="'$srcdir'/tls-certs/ca.pem"
+ tls.mycert="'$srcdir'/tls-certs/cert.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ tls.authmode="certvalid"
+ tls.permittedpeer="rsyslog"
+ tls.tlscfgcmd="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.2
+CipherString=ECDHE-RSA-AES256-GCM-SHA384
+Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.2,-TLSv1.3
+MinProtocol=TLSv1.2
+MaxProtocol=TLSv1.2")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+
+export TCPFLOOD_EXTRA_OPTS='-k "Protocol=ALL,-SSLv2,-SSLv3,-TLSv1.1,-TLSv1.2
+CipherString=DHE-RSA-AES256-SHA
+Protocol=ALL,-SSLv2,-SSLv3,-TLSv1.1,-TLSv1.2,-TLSv1.3
+MinProtocol=TLSv1.1
+MaxProtocol=TLSv1.1"'
+tcpflood --check-only -u "openssl" -Trelp-tls -acertvalid -p$TCPFLOOD_PORT -m$NUMMESSAGES -x "$srcdir/tls-certs/ca.pem" -z "$srcdir/tls-certs/key.pem" -Z "$srcdir/tls-certs/cert.pem" -Ersyslog 2> ${RSYSLOG_DYNNAME}.tcpflood
+
+shutdown_when_empty
+wait_shutdown
+
+content_check --check-only "relpTcpTLSSetPrio_gtls" ${RSYSLOG_DEBUGLOG}
+ret=$?
+if [ $ret == 0 ]; then
+ echo "SKIP: LIBRELP was build without OPENSSL Support"
+ skip_test
+fi
+
+content_check --check-only "OpenSSL Version too old" ${RSYSLOG_DEBUGLOG}
+ret=$?
+if [ $ret == 0 ]; then
+ echo "SKIP: OpenSSL Version too old"
+ skip_test
+else
+ # Check for a failed session - possible ecodes are 10031 and 10040
+ content_check "librelp: generic error: ecode" $RSYSLOG_DEBUGLOG
+fi
+
+exit_test \ No newline at end of file
diff --git a/tests/imrelp-tls-chainedcert.sh b/tests/imrelp-tls-chainedcert.sh
new file mode 100755
index 0000000..927c588
--- /dev/null
+++ b/tests/imrelp-tls-chainedcert.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# addd 2020-08-25 by alorbach, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+require_relpEngineVersion "1.7.0"
+export NUMMESSAGES=1000
+
+# uncomment for debugging support:
+# export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+# export RSYSLOG_DEBUGLOG="log"
+# export TCPFLOOD_EXTRA_OPTS="-v"
+
+do_skip=0
+generate_conf
+add_conf '
+# uncomment for debugging support:
+# $DebugFile debug.log
+# $DebugLevel 2
+
+module( load="../plugins/imrelp/.libs/imrelp"
+ tls.tlslib="openssl"
+)
+input(type="imrelp" port="'$TCPFLOOD_PORT'"
+ tls="on"
+ tls.mycert="'$srcdir'/tls-certs/certchained.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ tls.authmode="certvalid"
+ tls.permittedpeer="rsyslog")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+startup
+./tcpflood -u openssl -Trelp-tls -acertvalid -p$TCPFLOOD_PORT -m$NUMMESSAGES -z "$srcdir/tls-certs/key.pem" -Z "$srcdir/tls-certs/certchained.pem" -Ersyslog 2> $RSYSLOG_DYNNAME.tcpflood
+cat -n $RSYSLOG_DYNNAME.tcpflood
+shutdown_when_empty
+wait_shutdown
+
+# uncomment for debugging support:
+# cat debug.log
+
+if [ $do_skip -eq 1 ]; then
+ skip_test
+fi
+seq_check
+exit_test
diff --git a/tests/imrelp-tls-mixed-chainedcert.sh b/tests/imrelp-tls-mixed-chainedcert.sh
new file mode 100755
index 0000000..1273fab
--- /dev/null
+++ b/tests/imrelp-tls-mixed-chainedcert.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+# addd 2020-08-25 by alorbach, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+require_relpEngineVersion "1.7.0"
+export NUMMESSAGES=1000
+
+# uncomment for debugging support:
+export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+export TCPFLOOD_EXTRA_OPTS="-v"
+
+# Print Versions
+echo "OpenSSL Version:"
+openssl version
+
+echo "GnuTls Version:"
+gnutls-cli --version
+
+do_skip=0
+generate_conf
+add_conf '
+# uncomment for debugging support:
+# $DebugFile debug.log
+# $DebugLevel 2
+
+module( load="../plugins/imrelp/.libs/imrelp"
+ tls.tlslib="openssl"
+)
+input(type="imrelp" port="'$TCPFLOOD_PORT'"
+ tls="on"
+ tls.mycert="'$srcdir'/tls-certs/certchained.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ tls.authmode="certvalid"
+ tls.permittedpeer="rsyslog")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+startup
+./tcpflood -u gnutls -Trelp-tls -acertvalid -p$TCPFLOOD_PORT -m$NUMMESSAGES -z "$srcdir/tls-certs/key.pem" -Z "$srcdir/tls-certs/certchained.pem" -Ersyslog 2> $RSYSLOG_DYNNAME.tcpflood
+cat -n $RSYSLOG_DYNNAME.tcpflood
+shutdown_when_empty
+wait_shutdown
+
+# uncomment for debugging support:
+# cat debug.log
+
+if [ $do_skip -eq 1 ]; then
+ skip_test
+fi
+seq_check
+exit_test
diff --git a/tests/imrelp-tls-mixed-chainedcert2.sh b/tests/imrelp-tls-mixed-chainedcert2.sh
new file mode 100755
index 0000000..742f333
--- /dev/null
+++ b/tests/imrelp-tls-mixed-chainedcert2.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+# addd 2020-08-25 by alorbach, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+require_relpEngineVersion "1.7.0"
+export NUMMESSAGES=1000
+
+# uncomment for debugging support:
+export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+export TCPFLOOD_EXTRA_OPTS="-v"
+
+# Print Versions
+echo "OpenSSL Version:"
+openssl version
+
+echo "GnuTls Version:"
+gnutls-cli --version
+
+do_skip=0
+generate_conf
+add_conf '
+# uncomment for debugging support:
+# $DebugFile debug.log
+# $DebugLevel 2
+
+module( load="../plugins/imrelp/.libs/imrelp"
+ tls.tlslib="gnutls"
+)
+input(type="imrelp" port="'$TCPFLOOD_PORT'"
+ tls="on"
+ tls.mycert="'$srcdir'/tls-certs/certchained.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ tls.authmode="certvalid"
+ tls.permittedpeer="rsyslog")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+startup
+./tcpflood -u openssl -Trelp-tls -acertvalid -p$TCPFLOOD_PORT -m$NUMMESSAGES -z "$srcdir/tls-certs/key.pem" -Z "$srcdir/tls-certs/certchained.pem" -Ersyslog 2> $RSYSLOG_DYNNAME.tcpflood
+cat -n $RSYSLOG_DYNNAME.tcpflood
+shutdown_when_empty
+wait_shutdown
+
+# uncomment for debugging support:
+# cat debug.log
+
+if [ $do_skip -eq 1 ]; then
+ skip_test
+fi
+seq_check
+exit_test
diff --git a/tests/imrelp-tls.sh b/tests/imrelp-tls.sh
new file mode 100755
index 0000000..d0d88ae
--- /dev/null
+++ b/tests/imrelp-tls.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# addd 2019-01-31 by PascalWithopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+do_skip=0
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+input(type="imrelp" port="'$TCPFLOOD_PORT'" tls="on"
+ tls.cacert="'$srcdir'/tls-certs/ca.pem"
+ tls.mycert="'$srcdir'/tls-certs/cert.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ tls.authmode="certvalid"
+ tls.permittedpeer="rsyslog")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+./tcpflood -Trelp-tls -acertvalid -p$TCPFLOOD_PORT -m$NUMMESSAGES -x "$srcdir/tls-certs/ca.pem" -z "$srcdir/tls-certs/key.pem" -Z "$srcdir/tls-certs/cert.pem" -Ersyslog 2> $RSYSLOG_DYNNAME.tcpflood
+if [ $? -eq 1 ]; then
+ cat $RSYSLOG_DYNNAME.tcpflood
+ if ! grep "could net set.*certvalid" < "$RSYSLOG_DYNNAME.tcpflood" ; then
+ printf "librelp too old, need to skip this test\n"
+ do_skip=1
+ fi
+fi
+ cat -n $RSYSLOG_DYNNAME.tcpflood
+shutdown_when_empty
+wait_shutdown
+if [ $do_skip -eq 1 ]; then
+ skip_test
+fi
+seq_check
+exit_test
diff --git a/tests/imtcp-NUL-rawmsg.sh b/tests/imtcp-NUL-rawmsg.sh
new file mode 100755
index 0000000..f637d22
--- /dev/null
+++ b/tests/imtcp-NUL-rawmsg.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# addd 2016-05-13 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%rawmsg%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+echo '<167>Mar 6 16:57:54 172.20.245.8 test: msgnum:0 X test message
+<167>Mar 6 16:57:54 172.20.245.8 Xtest: msgnum:1 test message' | tr X '\000' > $RSYSLOG_DYNNAME.input
+tcpflood -B -I $RSYSLOG_DYNNAME.input
+shutdown_when_empty
+wait_shutdown
+echo '<167>Mar 6 16:57:54 172.20.245.8 test: msgnum:0 #000 test message
+<167>Mar 6 16:57:54 172.20.245.8 #000test: msgnum:1 test message' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid output generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi;
+exit_test
diff --git a/tests/imtcp-NUL.sh b/tests/imtcp-NUL.sh
new file mode 100755
index 0000000..8f1d27a
--- /dev/null
+++ b/tests/imtcp-NUL.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# addd 2016-05-13 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+echo '<167>Mar 6 16:57:54 172.20.245.8 test: msgnum:0 X test message
+<167>Mar 6 16:57:54 172.20.245.8 Xtest: msgnum:1 test message' | tr X '\000' > $RSYSLOG_DYNNAME.input
+tcpflood -B -I $RSYSLOG_DYNNAME.input
+shutdown_when_empty
+wait_shutdown
+seq_check 0 1
+exit_test
diff --git a/tests/imtcp-basic-hup.sh b/tests/imtcp-basic-hup.sh
new file mode 100755
index 0000000..0eb33d0
--- /dev/null
+++ b/tests/imtcp-basic-hup.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# added 2019-07-30 by RGerhards, released under ASL 2.0
+export NUMMESSAGES=4000 # MUST be an even number!
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2))
+issue_HUP
+tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) -i$((NUMMESSAGES / 2))
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-basic.sh b/tests/imtcp-basic.sh
new file mode 100755
index 0000000..314947c
--- /dev/null
+++ b/tests/imtcp-basic.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# addd 2016-05-13 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+tcpflood -m $NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-bigmessage-octetcounting.sh b/tests/imtcp-bigmessage-octetcounting.sh
new file mode 100755
index 0000000..1d9350b
--- /dev/null
+++ b/tests/imtcp-bigmessage-octetcounting.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# add 2020-05-14 by alorbach, released under ASL 2.0
+export NUMMESSAGES=10
+export TEST_BYTES_SENDSIZE=4037
+export TEST_BYTES_EXPECTED=$(((TEST_BYTES_SENDSIZE/2 - 420) * NUMMESSAGES)) # 262152
+. ${srcdir:=.}/diag.sh init
+
+generate_conf
+add_conf '
+global(
+ workDirectory="'$RSYSLOG_DYNNAME.spool'"
+ maxMessageSize="4k"
+)
+module( load="../plugins/imtcp/.libs/imtcp"
+ MaxSessions="10000"
+ discardTruncatedMsg="on"
+)
+input(
+ type="imtcp"
+ name="imtcp"
+ port="'$TCPFLOOD_PORT'"
+ ruleset="print"
+)
+
+template(name="print_message" type="list"){
+ constant(value="inputname: ")
+ property(name="inputname")
+ constant(value=", strlen: ")
+ property(name="$!strlen")
+ constant(value=", message: ")
+ property(name="msg")
+ constant(value="\n")
+}
+ruleset(name="print") {
+ set $!strlen = strlen($msg);
+ action(
+ type="omfile" template="print_message"
+ file=`echo $RSYSLOG_OUT_LOG`
+ )
+}
+'
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -d $TEST_BYTES_SENDSIZE -O
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+content_count_check --regex "inputname: imtcp, strlen:" ${NUMMESSAGES}
+
+count=$(wc -c < $RSYSLOG_OUT_LOG)
+if [ $count -lt $TEST_BYTES_EXPECTED ]; then
+ echo
+ echo "FAIL: expected bytes count $count did not match $TEST_BYTES_EXPECTED. "
+ echo
+ echo "First 100 bytes of $RSYSLOG_OUT_LOG are: "
+ head -c 100 $RSYSLOG_OUT_LOG
+ echo
+ echo "Last 100 bytes of $RSYSLOG_OUT_LOG are: "
+ tail -c 100 $RSYSLOG_OUT_LOG
+ error_exit 1
+else
+ echo "Found $count bytes (Expected $TEST_BYTES_EXPECTED) in $RSYSLOG_OUT_LOG"
+fi
+
+exit_test \ No newline at end of file
diff --git a/tests/imtcp-bigmessage-octetstuffing.sh b/tests/imtcp-bigmessage-octetstuffing.sh
new file mode 100755
index 0000000..35f9568
--- /dev/null
+++ b/tests/imtcp-bigmessage-octetstuffing.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# add 2020-05-14 by alorbach, released under ASL 2.0
+export NUMMESSAGES=10
+export TEST_BYTES_SENDSIZE=4037
+export TEST_BYTES_EXPECTED=$(((TEST_BYTES_SENDSIZE/2 - 420) * NUMMESSAGES)) # 262152
+. ${srcdir:=.}/diag.sh init
+
+generate_conf
+add_conf '
+global(
+ workDirectory="'$RSYSLOG_DYNNAME.spool'"
+ maxMessageSize="4k"
+)
+module( load="../plugins/imtcp/.libs/imtcp"
+ MaxSessions="10000"
+ discardTruncatedMsg="on"
+)
+input(
+ type="imtcp"
+ name="imtcp"
+ port="'$TCPFLOOD_PORT'"
+ ruleset="print"
+)
+
+template(name="print_message" type="list"){
+ constant(value="inputname: ")
+ property(name="inputname")
+ constant(value=", strlen: ")
+ property(name="$!strlen")
+ constant(value=", message: ")
+ property(name="msg")
+ constant(value="\n")
+}
+ruleset(name="print") {
+ set $!strlen = strlen($msg);
+ action(
+ type="omfile" template="print_message"
+ file=`echo $RSYSLOG_OUT_LOG`
+ )
+}
+'
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -d $TEST_BYTES_SENDSIZE
+
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+content_count_check --regex "inputname: imtcp, strlen:" ${NUMMESSAGES}
+
+count=$(wc -c < $RSYSLOG_OUT_LOG)
+if [ $count -lt $TEST_BYTES_EXPECTED ]; then
+ echo
+ echo "FAIL: expected bytes count $count did not match $TEST_BYTES_EXPECTED. "
+ echo
+ echo "First 100 bytes of $RSYSLOG_OUT_LOG are: "
+ head -c 100 $RSYSLOG_OUT_LOG
+ echo
+ echo "Last 100 bytes of $RSYSLOG_OUT_LOG are: "
+ tail -c 100 $RSYSLOG_OUT_LOG
+ error_exit 1
+else
+ echo "Found $count bytes (Expected $TEST_BYTES_EXPECTED) in $RSYSLOG_OUT_LOG"
+fi
+
+exit_test \ No newline at end of file
diff --git a/tests/imtcp-connection-msg-recieved.sh b/tests/imtcp-connection-msg-recieved.sh
new file mode 100755
index 0000000..60d3497
--- /dev/null
+++ b/tests/imtcp-connection-msg-recieved.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# addd 2021-05-10 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ notifyonconnectionopen="on" notifyonconnectionclose="on")
+
+:msg, contains, "msgnum:" {
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -m1 -M"\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\""
+shutdown_when_empty
+wait_shutdown
+content_check "connection established with "
+content_check "closed by remote peer "
+exit_test
diff --git a/tests/imtcp-discard-truncated-msg.sh b/tests/imtcp-discard-truncated-msg.sh
new file mode 100755
index 0000000..8782dec
--- /dev/null
+++ b/tests/imtcp-discard-truncated-msg.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# addd 2016-05-13 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 128
+global(processInternalMessages="on")
+module(load="../plugins/imtcp/.libs/imtcp" discardTruncatedMsg="on")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%rawmsg%\n")
+ruleset(name="ruleset1") {
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+tcpflood -m1 -M "\"<30>Apr 6 13:21:08 docker/6befb258da22[6128]: TOO LONG bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb123456789B123456789Ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+<30>Apr 6 13:21:09 docker/6defd258da22[6128]: NEXT_MSG\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='<30>Apr 6 13:21:08 docker/6befb258da22[6128]: TOO LONG bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb123456789B12
+<30>Apr 6 13:21:09 docker/6defd258da22[6128]: NEXT_MSG'
+cmp_exact
+
+exit_test
diff --git a/tests/imtcp-drvr-in-input-basic.sh b/tests/imtcp-drvr-in-input-basic.sh
new file mode 100755
index 0000000..5ca98d3
--- /dev/null
+++ b/tests/imtcp-drvr-in-input-basic.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2021-04-27 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-listen-port-file-2.sh b/tests/imtcp-listen-port-file-2.sh
new file mode 100755
index 0000000..1508536
--- /dev/null
+++ b/tests/imtcp-listen-port-file-2.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# This test checks if more than one port file names work correctly for
+# imtcp. See also:
+# https://github.com/rsyslog/rsyslog/issues/3817
+# added 2019-08-14 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.rcvr_port"
+ ruleset="rs1")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.rcvr_port2"
+ ruleset="rs2")
+
+ruleset(name="rs1") {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME.1.log'" template="outfmt")
+}
+
+ruleset(name="rs2") {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME.2.log'" template="outfmt")
+}
+'
+startup
+assign_file_content RCVR_PORT "$RSYSLOG_DYNNAME.rcvr_port"
+assign_file_content RCVR_PORT2 "$RSYSLOG_DYNNAME.rcvr_port2"
+./tcpflood -p $RCVR_PORT -m10
+./tcpflood -p $RCVR_PORT2 -m10 -i10
+shutdown_when_empty
+wait_shutdown
+printf 'checking receiver 1\n'
+export SEQ_CHECK_FILE="$RSYSLOG_DYNNAME.1.log"
+seq_check 0 9
+printf 'checking receiver 2\n'
+export SEQ_CHECK_FILE="$RSYSLOG_DYNNAME.2.log"
+seq_check 10 19
+exit_test
diff --git a/tests/imtcp-maxFrameSize.sh b/tests/imtcp-maxFrameSize.sh
new file mode 100755
index 0000000..a580f78
--- /dev/null
+++ b/tests/imtcp-maxFrameSize.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# addd 2016-05-13 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(processInternalMessages="on")
+module(load="../plugins/imtcp/.libs/imtcp" maxFrameSize="100")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m1 -M "\"1005 <120> 2011-03-01T11:22:12Z host tag: this is a way too long message\""
+shutdown_when_empty
+wait_shutdown
+
+grep "Framing Error.*change to octet stuffing" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message from imtcp not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+
+exit_test
diff --git a/tests/imtcp-msg-truncation-on-number.sh b/tests/imtcp-msg-truncation-on-number.sh
new file mode 100755
index 0000000..5dd2532
--- /dev/null
+++ b/tests/imtcp-msg-truncation-on-number.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# addd 2016-05-13 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 128
+global(processInternalMessages="on"
+ oversizemsg.input.mode="accept")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way too long message that has ab
+9876543210 cdefghijklmn test8 test9 test10 test11 test12 test13 test14 test15 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk tag: testtesttesttesttesttesttesttesttest\""
+shutdown_when_empty
+wait_shutdown
+
+grep "Framing Error in received" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message from imtcp not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+grep "9876543210cdefghijklmn test8 test9 test10 test11 test12 test13 test14 test15 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk tag: testtestt" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected date from imtcp not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/imtcp-msg-truncation-on-number2.sh b/tests/imtcp-msg-truncation-on-number2.sh
new file mode 100755
index 0000000..d099fb5
--- /dev/null
+++ b/tests/imtcp-msg-truncation-on-number2.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# addd 2016-05-13 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 128
+global(processInternalMessages="on")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="templ1" type="string" string="%rawmsg%\n")
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="templ1")
+}
+'
+startup
+tcpflood -m2 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"214000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"214000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"2000000010 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"4000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+tcpflood -m1 -M "\"0 <120> 2011-03-01T11:22:12Z host msgnum:1\""
+shutdown_when_empty
+wait_shutdown
+
+echo '<120> 2011-03-01T11:22:12Z host msgnum:1
+<120> 2011-03-01T11:22:12Z host msgnum:1
+214000000000<120> 2011-03-01T11:22:12Z host msgnum:1
+<120> 2011-03-01T11:22:12Z host msgnum:1
+214000000000<120> 2011-03-01T11:22:12Z host msgnum:1
+<120> 2011-03-01T11:22:12Z host msgnum:1
+2000000010<120> 2011-03-01T11:22:12Z host msgnum:1
+4000000000<120> 2011-03-01T11:22:12Z host msgnum:1
+<120> 2011-03-01T11:22:12Z host msgnum:1' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imtcp-multi-drvr-basic-parallel.sh b/tests/imtcp-multi-drvr-basic-parallel.sh
new file mode 100755
index 0000000..a8de39a
--- /dev/null
+++ b/tests/imtcp-multi-drvr-basic-parallel.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# This test checks imtcp functionality with multiple drivers running together. It is
+# a minimal test.
+# added 2021-04-27 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100000 # must be even number!
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port2")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+assign_tcpflood_port2 "$RSYSLOG_DYNNAME.tcpflood_port2"
+# Note: the two tcpflood instances are run in parallel with intent!
+# It stresses the rsyslog engine a bit more. If this fails, see if
+# the non-parallel test also fails. If so, debug that one, because it
+# is easier to do!
+tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem &
+tcpflood -p$TCPFLOOD_PORT2 -m$((NUMMESSAGES / 2)) -i$((NUMMESSAGES / 2))
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh b/tests/imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh
new file mode 100755
index 0000000..c3be9f9
--- /dev/null
+++ b/tests/imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# This test checks imtcp functionality with multiple drivers running together. It is
+# a minimal test.
+# added 2021-04-27 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=60000 # must be evenly dividable by 3
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ name="i1"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+
+input(type="imtcp" name="i2" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port2")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port3"
+ name="i3"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port3" name="i3")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+assign_tcpflood_port2 "$RSYSLOG_DYNNAME.tcpflood_port2"
+assign_rs_port "$RSYSLOG_DYNNAME.tcpflood_port3"
+tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 3)) -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+tcpflood -p$TCPFLOOD_PORT2 -m$((NUMMESSAGES / 3)) -i$((NUMMESSAGES / 3))
+tcpflood -p$RS_PORT -m$((NUMMESSAGES / 3)) -i$((NUMMESSAGES / 3 * 2)) -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-multi-drvr-basic.sh b/tests/imtcp-multi-drvr-basic.sh
new file mode 100755
index 0000000..13edafb
--- /dev/null
+++ b/tests/imtcp-multi-drvr-basic.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# This test checks imtcp functionality with multiple drivers running together. It is
+# a minimal test.
+# added 2021-04-27 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000 # must be even number!
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port2")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+assign_tcpflood_port2 "$RSYSLOG_DYNNAME.tcpflood_port2"
+tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+tcpflood -p$TCPFLOOD_PORT2 -m$((NUMMESSAGES / 2)) -i$((NUMMESSAGES / 2))
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-multiport.sh b/tests/imtcp-multiport.sh
new file mode 100755
index 0000000..7516be0
--- /dev/null
+++ b/tests/imtcp-multiport.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# Test for multiple ports in imtcp
+# This test checks if multiple tcp listener ports are correctly
+# handled by imtcp
+# added 2009-05-22 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=30000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" name="i1")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port2" name="i2")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port3" name="i3")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+assign_tcpflood_port2 "$RSYSLOG_DYNNAME.tcpflood_port2"
+assign_rs_port "$RSYSLOG_DYNNAME.tcpflood_port3"
+tcpflood -p$TCPFLOOD_PORT -m10000
+tcpflood -p$TCPFLOOD_PORT2 -i10000 -m10000
+tcpflood -p$RS_PORT -i20000 -m10000
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-octet-framing-too-long-vg.sh b/tests/imtcp-octet-framing-too-long-vg.sh
new file mode 100755
index 0000000..88e8a14
--- /dev/null
+++ b/tests/imtcp-octet-framing-too-long-vg.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# added 2022-04-25 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MaxMessageSize 128
+global(processInternalMessages="on"
+ oversizemsg.input.mode="accept")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup_vg
+echo "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000 <120> 2011-03-01T11:22:12Z host tag: this is a way too long message that has to be truncatedtest1 test2 test3 test4 test5 ab" > $RSYSLOG_DYNNAME.inputfile
+tcpflood -I $RSYSLOG_DYNNAME.inputfile
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+# the prime objective is to see if valgrind check is ok, but we also do a quick content check (just in case)
+content_check "received oversize message from peer"
+exit_test
diff --git a/tests/imtcp-tls-basic-verifydepth.sh b/tests/imtcp-tls-basic-verifydepth.sh
new file mode 100755
index 0000000..d057b3a
--- /dev/null
+++ b/tests/imtcp-tls-basic-verifydepth.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# added 2011-02-28 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.TlsVerifyDepth="5"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/certvalid" )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+
+# Begin actual testcase
+startup
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-basic-vg.sh b/tests/imtcp-tls-basic-vg.sh
new file mode 100755
index 0000000..4648389
--- /dev/null
+++ b/tests/imtcp-tls-basic-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imtcp-tls-basic.sh
diff --git a/tests/imtcp-tls-basic.sh b/tests/imtcp-tls-basic.sh
new file mode 100755
index 0000000..b65e7c4
--- /dev/null
+++ b/tests/imtcp-tls-basic.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# added 2011-02-28 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+export TB_TEST_MAX_RUNTIME=1500
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog"
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem")
+
+module(load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-gtls-x509fingerprint-invld.sh b/tests/imtcp-tls-gtls-x509fingerprint-invld.sh
new file mode 100755
index 0000000..af33b45
--- /dev/null
+++ b/tests/imtcp-tls-gtls-x509fingerprint-invld.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# added 2018-12-22 by Rainer Gerhards
+# check for INVALID fingerprint!
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/fingerprint"
+ PermittedPeer=["SHA1:FF:C6:62:D5:9D:25:9F:BC:F3:CB:61:FA:D2:B3:8B:61:88:D7:06:C3"] # INVALID!
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+content_check --regex "peer fingerprint .* unknown"
+exit_test
diff --git a/tests/imtcp-tls-gtls-x509fingerprint.sh b/tests/imtcp-tls-gtls-x509fingerprint.sh
new file mode 100755
index 0000000..8cadd29
--- /dev/null
+++ b/tests/imtcp-tls-gtls-x509fingerprint.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# added 2018-12-22 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/fingerprint"
+ PermittedPeer=["SHA1:5C:C6:62:D5:9D:25:9F:BC:F3:CB:61:FA:D2:B3:8B:61:88:D7:06:C3"]
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omfile"
+ template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-gtls-x509name-invld.sh b/tests/imtcp-tls-gtls-x509name-invld.sh
new file mode 100755
index 0000000..c1c541d
--- /dev/null
+++ b/tests/imtcp-tls-gtls-x509name-invld.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2018-12-22 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/name"
+ PermittedPeer=["INVALID"]
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+content_check --regex "peer name not authorized"
+exit_test
diff --git a/tests/imtcp-tls-gtls-x509name-legacy.sh b/tests/imtcp-tls-gtls-x509name-legacy.sh
new file mode 100755
index 0000000..4e8878c
--- /dev/null
+++ b/tests/imtcp-tls-gtls-x509name-legacy.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+
+
+# NOTE: we intentionally use legacy statements here! This *IS* what we want to test!
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$DefaultNetstreamDriver gtls
+$inputTcpserverStreamdriverPermittedPeer rsyslog-client
+
+$InputTCPServerStreamDriverAuthMode x509/name
+$InputTCPServerStreamDriverPermittedPeer Log_Streaming_Client
+$InputTCPServerStreamDriverMode 1
+$InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port
+$InputTCPServerRun 0
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omfile"
+ template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-gtls-x509name.sh b/tests/imtcp-tls-gtls-x509name.sh
new file mode 100755
index 0000000..81d9ca5
--- /dev/null
+++ b/tests/imtcp-tls-gtls-x509name.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# added 2018-12-22 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/name"
+ PermittedPeer=["rsyslog-client"]
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omfile"
+ template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-input-2certs.sh b/tests/imtcp-tls-input-2certs.sh
new file mode 100755
index 0000000..c31724f
--- /dev/null
+++ b/tests/imtcp-tls-input-2certs.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# added 2021-08-03 by Rgerhards
+# check that we do use the proper set of certificates
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+# The default shall NOT be used - if so, tcpflood would err out!
+
+global( defaultNetstreamDriverCAFile="'$srcdir'/testsuites/x.509/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/testsuites/x.509/machine-cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/testsuites/x.509/machine-key.pem")
+
+module(load="../plugins/imtcp/.libs/imtcp"
+ permittedPeer="SHA1:5C:C6:62:D5:9D:25:9F:BC:F3:CB:61:FA:D2:B3:8B:61:88:D7:06:C3"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/fingerprint" )
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ streamDriver.CAFile="'$srcdir'/tls-certs/ca.pem"
+ streamDriver.CertFile="'$srcdir'/tls-certs/cert.pem"
+ streamDriver.KeyFile="'$srcdir'/tls-certs/key.pem")
+
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-input-basic.sh b/tests/imtcp-tls-input-basic.sh
new file mode 100755
index 0000000..4f52302
--- /dev/null
+++ b/tests/imtcp-tls-input-basic.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2011-02-28 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ streamDriver.CAFile="'$srcdir'/tls-certs/ca.pem"
+ streamDriver.CertFile="'$srcdir'/tls-certs/cert.pem"
+ streamDriver.KeyFile="'$srcdir'/tls-certs/key.pem")
+
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-no-lstn-startup.sh b/tests/imtcp-tls-no-lstn-startup.sh
new file mode 100755
index 0000000..e18fc8e
--- /dev/null
+++ b/tests/imtcp-tls-no-lstn-startup.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# added 2021-07-07 by Rgerhards
+# This test checks if rsyslog handles a non-starting imtcp listener gracefully.
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem")
+
+module(load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+
+input(type="imtcp" port="invalid-does-not-exist")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+#tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/imtcp-tls-ossl-basic-brokenhandshake-vg.sh b/tests/imtcp-tls-ossl-basic-brokenhandshake-vg.sh
new file mode 100755
index 0000000..4e2ba98
--- /dev/null
+++ b/tests/imtcp-tls-ossl-basic-brokenhandshake-vg.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+if [ "$(valgrind --version)" == "valgrind-3.11.0" ]; then
+ printf 'This test does NOT work with valgrind-3.11.0 - valgrind always reports\n'
+ printf 'a valgrind-internal bug. So we need to skip it.\n'
+ exit 77
+fi
+. ${srcdir:=.}/diag.sh init
+export USE_VALGRIND="YES"
+export NUMMESSAGES=1
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omfile"
+ template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+# Begin actual testcase | send one msg without TLS to force a handshake failure, send second msg with TLS to make the test PASS
+startup
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-ossl-basic-tlscommands.sh b/tests/imtcp-tls-ossl-basic-tlscommands.sh
new file mode 100755
index 0000000..6f2e760
--- /dev/null
+++ b/tests/imtcp-tls-ossl-basic-tlscommands.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# added 2018-04-27 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon"
+ gnutlsPriorityString="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.2
+ Options=Bugs"
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+
+# now inject the messages which will fail due protocol configuration
+tcpflood --check-only -k "Protocol=-ALL,TLSv1.2" -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+
+shutdown_when_empty
+wait_shutdown
+
+if content_check --check-only "TLS library does not support SSL_CONF_cmd"
+then
+ echo "SKIP: TLS library does not support SSL_CONF_cmd"
+ skip_test
+else
+ if content_check --check-only "SSL_ERROR_SYSCALL"
+ then
+ # Found SSL_ERROR_SYSCALL errorcode, no further check needed
+ exit_test
+ else
+ # Check for a SSL_ERROR_SSL error code
+ content_check "SSL_ERROR_SSL"
+ content_check "OpenSSL Error Stack:"
+ fi
+fi
+
+exit_test
diff --git a/tests/imtcp-tls-ossl-basic-verifydepth.sh b/tests/imtcp-tls-ossl-basic-verifydepth.sh
new file mode 100755
index 0000000..1a4de87
--- /dev/null
+++ b/tests/imtcp-tls-ossl-basic-verifydepth.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# added 2020-01-08 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.TlsVerifyDepth="5"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/certvalid" )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+
+# Begin actual testcase
+startup
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-ossl-basic-vg.sh b/tests/imtcp-tls-ossl-basic-vg.sh
new file mode 100755
index 0000000..951c54c
--- /dev/null
+++ b/tests/imtcp-tls-ossl-basic-vg.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+if [ "$(valgrind --version)" == "valgrind-3.11.0" ]; then
+ printf 'This test does NOT work with valgrind-3.11.0 - valgrind always reports\n'
+ printf 'a valgrind-internal bug. So we need to skip it.\n'
+ exit 77
+fi
+export USE_VALGRIND="YES"
+# not working on CENTOS 7 export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes"
+source ${srcdir:-.}/imtcp-tls-ossl-basic.sh
diff --git a/tests/imtcp-tls-ossl-basic.sh b/tests/imtcp-tls-ossl-basic.sh
new file mode 100755
index 0000000..0d17e3c
--- /dev/null
+++ b/tests/imtcp-tls-ossl-basic.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# added 2018-04-27 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10000
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+# debug.whitelist="on"
+# debug.files=["net_ossl.c", "nsd_ossl.c", "nsd_ptcp.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omfile"
+ template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+# Begin actual testcase
+startup
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-ossl-error-ca.sh b/tests/imtcp-tls-ossl-error-ca.sh
new file mode 100755
index 0000000..460c8c0
--- /dev/null
+++ b/tests/imtcp-tls-ossl-error-ca.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# added 2018-11-07 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca-fail.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/cert.pem'"
+)
+
+module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+# note: we do not need to generate any messages, config error occurs on startup
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "Error: CA certificate could not be accessed"
+content_check "OpenSSL Error Stack:"
+exit_test
diff --git a/tests/imtcp-tls-ossl-error-cert.sh b/tests/imtcp-tls-ossl-error-cert.sh
new file mode 100755
index 0000000..5e8c129
--- /dev/null
+++ b/tests/imtcp-tls-ossl-error-cert.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# added 2018-11-07 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert-fail.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/cert.pem'"
+)
+
+module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+# note: we do not need to generate any messages, config error occurs on startup
+startup
+sleep 5 # TODO: FIXME - just checking if we terminate too early
+shutdown_when_empty
+wait_shutdown
+content_check "Error: Certificate file could not be accessed"
+content_check "OpenSSL Error Stack:"
+exit_test
diff --git a/tests/imtcp-tls-ossl-error-key.sh b/tests/imtcp-tls-ossl-error-key.sh
new file mode 100755
index 0000000..beaf800
--- /dev/null
+++ b/tests/imtcp-tls-ossl-error-key.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# added 2018-11-07 by Rainer Gerhards
+# check error message on cert as key file
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/cert.pem'"
+)
+
+module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+# note: we do not need to generate any messages, config error occurs on startup
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "Error: Key could not be accessed"
+content_check "OpenSSL Error Stack:"
+exit_test
diff --git a/tests/imtcp-tls-ossl-error-key2.sh b/tests/imtcp-tls-ossl-error-key2.sh
new file mode 100755
index 0000000..4202cc0
--- /dev/null
+++ b/tests/imtcp-tls-ossl-error-key2.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# added 2018-11-07 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key-fail.pem'"
+)
+
+module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+# note: we do not need to generate any messages, config error occurs on startup
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "Error: Key could not be accessed"
+content_check "OpenSSL Error Stack:"
+exit_test
diff --git a/tests/imtcp-tls-ossl-input-2certs.sh b/tests/imtcp-tls-ossl-input-2certs.sh
new file mode 100755
index 0000000..c23c413
--- /dev/null
+++ b/tests/imtcp-tls-ossl-input-2certs.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# added 2021-08-03 by Rgerhards
+# check that we do use the proper set of certificates
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+# The default shall NOT be used - if so, tcpflood would err out!
+
+global( defaultNetstreamDriverCAFile="'$srcdir'/testsuites/x.509/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/testsuites/x.509/machine-cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/testsuites/x.509/machine-key.pem")
+
+module(load="../plugins/imtcp/.libs/imtcp"
+ permittedPeer="SHA1:5C:C6:62:D5:9D:25:9F:BC:F3:CB:61:FA:D2:B3:8B:61:88:D7:06:C3"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/fingerprint" )
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ streamDriver.CAFile="'$srcdir'/tls-certs/ca.pem"
+ streamDriver.CertFile="'$srcdir'/tls-certs/cert.pem"
+ streamDriver.KeyFile="'$srcdir'/tls-certs/key.pem")
+
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-ossl-input-basic.sh b/tests/imtcp-tls-ossl-input-basic.sh
new file mode 100755
index 0000000..3c9a7b1
--- /dev/null
+++ b/tests/imtcp-tls-ossl-input-basic.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# added 2011-02-28 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+global(
+# debug.whitelist="on"
+# debug.files=["net_ossl.c", "nsd_ossl.c", "nsd_ptcp.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module(load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port"
+ streamDriver.CAFile="'$srcdir'/tls-certs/ca.pem"
+ streamDriver.CertFile="'$srcdir'/tls-certs/cert.pem"
+ streamDriver.KeyFile="'$srcdir'/tls-certs/key.pem")
+
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-ossl-invalid-verifydepth.sh b/tests/imtcp-tls-ossl-invalid-verifydepth.sh
new file mode 100755
index 0000000..6df20c4
--- /dev/null
+++ b/tests/imtcp-tls-ossl-invalid-verifydepth.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ streamdriver.TlsVerifyDepth="1" )
+
+# input is not really needed, just given for completeness
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "streamdriver.TlsVerifyDepth must be 2 or higher"
+
+exit_test
diff --git a/tests/imtcp-tls-ossl-x509fingerprint.sh b/tests/imtcp-tls-ossl-x509fingerprint.sh
new file mode 100755
index 0000000..59167b0
--- /dev/null
+++ b/tests/imtcp-tls-ossl-x509fingerprint.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# added 2018-04-27 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/fingerprint"
+ PermittedPeer=["SHA1:5C:C6:62:D5:9D:25:9F:BC:F3:CB:61:FA:D2:B3:8B:61:88:D7:06:C3"]
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omfile"
+ template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-ossl-x509name.sh b/tests/imtcp-tls-ossl-x509name.sh
new file mode 100755
index 0000000..fadd7f1
--- /dev/null
+++ b/tests/imtcp-tls-ossl-x509name.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# added 2018-04-27 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/name"
+ PermittedPeer=["/CN=rsyslog-client/OU=Adiscon GmbH/O=Adiscon GmbH/L=Grossrinderfeld/ST=BW/C=DE/DC=rsyslog.com","rsyslog.com"]
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omfile"
+ template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+wait_file_lines
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp-tls-ossl-x509valid.sh b/tests/imtcp-tls-ossl-x509valid.sh
new file mode 100755
index 0000000..a796daa
--- /dev/null
+++ b/tests/imtcp-tls-ossl-x509valid.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# added 2018-04-27 by alorbach
+# This file is part of the rsyslog project, released under GPLv3
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10000
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/certvalid" )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omfile"
+ template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+# Begin actual testcase
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+wait_file_lines
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp_addtlframedelim.sh b/tests/imtcp_addtlframedelim.sh
new file mode 100755
index 0000000..0b217fe
--- /dev/null
+++ b/tests/imtcp_addtlframedelim.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2010-08-11 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=20000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp" addtlframedelimiter="0")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+local0.* ./'$RSYSLOG_OUT_LOG';outfmt
+'
+startup
+tcpflood -m$NUMMESSAGES -F0 -P129
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp_addtlframedelim_on_input.sh b/tests/imtcp_addtlframedelim_on_input.sh
new file mode 100755
index 0000000..a2618d9
--- /dev/null
+++ b/tests/imtcp_addtlframedelim_on_input.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2010-08-11 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=20000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" addtlframedelimiter="0")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+local0.* ./'$RSYSLOG_OUT_LOG';outfmt
+'
+startup
+tcpflood -m$NUMMESSAGES -F0 -P129
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/imtcp_conndrop.sh b/tests/imtcp_conndrop.sh
new file mode 100755
index 0000000..676c3e0
--- /dev/null
+++ b/tests/imtcp_conndrop.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Test imtcp with many dropping connections
+# added 2010-08-10 by Rgerhards
+#
+# This file is part of the rsyslog project, released under GPLv3
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test currently does not work on FreeBSD"
+export NUMMESSAGES=50000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+$MaxMessageSize 10k
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+$OMFileFlushInterval 2
+$OMFileIOBufferSize 256k
+local0.* ?dynfile;outfmt
+'
+startup
+# 100 byte messages to gain more practical data use
+tcpflood -c20 -m$NUMMESSAGES -r -d100 -P129 -D
+shutdown_when_empty
+wait_shutdown
+export SEQ_CHECK_OPTIONS=-E
+seq_check
+exit_test
diff --git a/tests/imtcp_conndrop_tls-vg.sh b/tests/imtcp_conndrop_tls-vg.sh
new file mode 100755
index 0000000..d2de6e8
--- /dev/null
+++ b/tests/imtcp_conndrop_tls-vg.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+export TB_TEST_MAX_RUNTIME=1500
+export NUMMESSAGES=10000 # reduce for slower valgrind run
+source ${srcdir:-.}/imtcp_conndrop_tls.sh
diff --git a/tests/imtcp_conndrop_tls.sh b/tests/imtcp_conndrop_tls.sh
new file mode 100755
index 0000000..1b9e38b
--- /dev/null
+++ b/tests/imtcp_conndrop_tls.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Test imtcp/TLS with many dropping connections
+# added 2011-06-09 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+global( maxMessageSize="10k"
+ defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem"
+ defaultNetstreamDriver="gtls"
+ debug.whitelist="on"
+ debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module(load="../plugins/imtcp/.libs/imtcp" maxSessions="1100"
+ streamDriver.mode="1" streamDriver.authMode="anon")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+local0.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+# 100 byte messages to gain more practical data use
+tcpflood -c20 -p$TCPFLOOD_PORT -m$NUMMESSAGES -r -d100 -P129 -D -l0.995 -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem
+shutdown_when_empty
+wait_shutdown
+export SEQ_CHECK_OPTIONS=-E
+seq_check
+exit_test
diff --git a/tests/imtcp_incomplete_frame_at_end.sh b/tests/imtcp_incomplete_frame_at_end.sh
new file mode 100755
index 0000000..85d6e94
--- /dev/null
+++ b/tests/imtcp_incomplete_frame_at_end.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Copyright (C) 2016 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="list") {
+ property(name="msg")
+ constant(value="\n")
+}
+:msg, contains, "lastmsg" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+echo -n "<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 tcpflood 8710 - - lastmsg" >$RSYSLOG_DYNNAME.tmp
+tcpflood -I $RSYSLOG_DYNNAME.tmp
+rm $RSYSLOG_DYNNAME.tmp
+./msleep 500
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+export EXPECTED="lastmsg"
+cmp_exact
+exit_test
diff --git a/tests/imtcp_no_octet_counted.sh b/tests/imtcp_no_octet_counted.sh
new file mode 100755
index 0000000..a17174b
--- /dev/null
+++ b/tests/imtcp_no_octet_counted.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+echo ====================================================================================
+echo TEST: \[imtcp_no_octet_counted.sh\]: test imtcp with octet counted framing disabled
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="remote" supportOctetCountedFraming="off")
+
+template(name="outfmt" type="string" string="%rawmsg%\n")
+ruleset(name="remote") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -B -I ${srcdir}/testsuites/no_octet_counted.testdata
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+seq_check 0 19
+exit_test
diff --git a/tests/imtcp_spframingfix.sh b/tests/imtcp_spframingfix.sh
new file mode 100755
index 0000000..3292c54
--- /dev/null
+++ b/tests/imtcp_spframingfix.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ====================================================================================
+echo TEST: \[imptcp_spframingfix.sh\]: test imptcp in regard to Cisco ASA framing fix
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="remote" framingfix.cisco.asa="on")
+
+template(name="outfmt" type="string" string="%rawmsg:6:7%\n")
+ruleset(name="remote") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -B -I ${srcdir}/testsuites/spframingfix.testdata
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+seq_check 0 19
+exit_test
diff --git a/tests/imtuxedoulog_data.sh b/tests/imtuxedoulog_data.sh
new file mode 100755
index 0000000..85eed65
--- /dev/null
+++ b/tests/imtuxedoulog_data.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imtuxedoulog/.libs/imtuxedoulog")
+input(type="imtuxedoulog" ruleset="ruleset"
+ severity="info" facility="local0"
+ maxlinesatonce="100" persiststateinterval="10"
+ maxsubmitatonce="100" tag="domain"
+ ulogbase="./'$RSYSLOG_DYNNAME'")
+ruleset(name="ruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="RSYSLOG_SyslogProtocol23Format")
+}
+'
+{
+ echo '164313.15.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree'
+ echo '164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree'
+ echo '164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)'
+ echo '164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1'
+ echo '164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)'
+} > $RSYSLOG_DYNNAME.$(date "+%m%d%y")
+logdate=$(date "+%Y-%m-%d")
+startup
+shutdown_when_empty
+wait_shutdown
+{
+echo '<134>1 '${logdate}'T16:43:13.15 tst-tmsm1 domain ARTIMPP_UDB.40042721.1 - - TRACE:at: } tpfree'
+echo '<134>1 '${logdate}'T16:43:13.151 tst-tmsm1 domain ARTIMPP_UDB.40042722.1 - [ECID="000001833E1D4i^5pVl3iY00f02M003UF^"] TRACE:at: } tpfree'
+echo '<134>1 '${logdate}'T16:43:13.152 tst-tmsm1 domain ARTIMPP_UDB.40042722.1 - [ECID="000001833E1D4i^5pVl3iY00f02B003UF^"] TRACE:at: { tpcommit(0x0)'
+echo '<134>1 '${logdate}'T16:43:13.153 tst-tmsm1 domain ARTIMPP_UDB.40042722.1 - [ECID="000001833E1D4i^5pVl3iY00f02M003SF^"] TRACE:at: } tpcommit = 1'
+echo '<134>1 '${logdate}'T16:43:13.154 tst-tmsm1 domain ARTIMPP_UDB.40042722.1 - [ECID="000001833E1D4i^5pVl3iY00f02M003VF^"] TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)'
+} | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/imtuxedoulog_errmsg_no_params-vg.sh b/tests/imtuxedoulog_errmsg_no_params-vg.sh
new file mode 100755
index 0000000..b9effbc
--- /dev/null
+++ b/tests/imtuxedoulog_errmsg_no_params-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/imtuxedoulog_errmsg_no_params.sh
diff --git a/tests/imtuxedoulog_errmsg_no_params.sh b/tests/imtuxedoulog_errmsg_no_params.sh
new file mode 100755
index 0000000..536f5be
--- /dev/null
+++ b/tests/imtuxedoulog_errmsg_no_params.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/imtuxedoulog/.libs/imtuxedoulog")
+
+input(type="imtuxedoulog")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter 'ulogbase' required but not specified"
+
+exit_test
diff --git a/tests/imudp_thread_hang.sh b/tests/imudp_thread_hang.sh
new file mode 100755
index 0000000..1603d71
--- /dev/null
+++ b/tests/imudp_thread_hang.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# the whole point of this test is just to check that imudp
+# does not block rsyslog termination. This test was introduced
+# after we had a regression where imudp's worker threads were
+# not properly terminated.
+# Copyright 2014 by Rainer Gerhards, licensed under ASL 2.0
+echo \[imudp_thread_hang\]: a situation where imudp caused a hang
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+
+module(load="../plugins/imudp/.libs/imudp" threads="3")
+input(type="imudp" Address="127.0.0.1" Port="20514")
+'
+startup
+./msleep 1000
+shutdown_immediate
+wait_shutdown
+exit_test
diff --git a/tests/imuxsock_ccmiddle.sh b/tests/imuxsock_ccmiddle.sh
new file mode 100755
index 0000000..6e53a8f
--- /dev/null
+++ b/tests/imuxsock_ccmiddle.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# test trailing LF handling in imuxsock
+. ${srcdir:=.}/diag.sh init
+./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1
+no_liblogging_stdlog=$?
+if [ $no_liblogging_stdlog -ne 0 ];then
+ echo "liblogging-stdlog not available - skipping test"
+ exit 77
+fi
+
+export NUMMESSAGES=1
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off")
+input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket")
+
+template(name="outfmt" type="string" string="%msg:%\n")
+local1.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+# send a message with trailing LF
+./syslog_caller -fsyslog_inject-c -m1 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=" test 1#0112"
+cmp_exact
+exit_test
diff --git a/tests/imuxsock_ccmiddle_root.sh b/tests/imuxsock_ccmiddle_root.sh
new file mode 100755
index 0000000..0a8405c
--- /dev/null
+++ b/tests/imuxsock_ccmiddle_root.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# note: we must be root and no other syslogd running in order to
+# carry out this test
+echo \[imuxsock_ccmiddle_root.sh\]: test trailing LF handling in imuxsock
+echo This test must be run as root with no other active syslogd
+if [ "$EUID" -ne 0 ]; then
+ exit 77 # Not root, skip this test
+fi
+./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1
+no_liblogging_stdlog=$?
+if [ $no_liblogging_stdlog -ne 0 ];then
+ echo "liblogging-stdlog not available - skipping test"
+ exit 77
+fi
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$ModLoad ../plugins/imuxsock/.libs/imuxsock
+
+$template outfmt,"%msg:%\n"
+local1.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+# send a message with trailing LF
+./syslog_caller -fsyslog_inject-c -m1
+# the sleep below is needed to prevent too-early termination of rsyslogd
+./msleep 100
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+export EXPECTED=" test 1#0112"
+cmp_exact
+exit_test
diff --git a/tests/imuxsock_ccmiddle_syssock.sh b/tests/imuxsock_ccmiddle_syssock.sh
new file mode 100755
index 0000000..431628f
--- /dev/null
+++ b/tests/imuxsock_ccmiddle_syssock.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# test trailing LF handling in imuxsock
+# part of rsyslog, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+uname
+if [ $(uname) = "SunOS" ] ; then
+ echo "Solaris: FIX ME"
+ exit 77
+fi
+
+./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1
+no_liblogging_stdlog=$?
+if [ $no_liblogging_stdlog -ne 0 ];then
+ echo "liblogging-stdlog not available - skipping test"
+ exit 77
+fi
+
+export NUMMESSAGES=1
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imuxsock/.libs/imuxsock"
+ SysSock.name="'$RSYSLOG_DYNNAME'-testbench_socket")
+
+template(name="outfmt" type="string" string="%msg:%\n")
+local1.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+# send a message with trailing LF
+./syslog_caller -fsyslog_inject-c -m1 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=" test 1#0112"
+cmp_exact
+exit_test
diff --git a/tests/imuxsock_hostname.sh b/tests/imuxsock_hostname.sh
new file mode 100755
index 0000000..6dcbd4e
--- /dev/null
+++ b/tests/imuxsock_hostname.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# test set hostname
+. ${srcdir:=.}/diag.sh init
+
+./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1
+no_liblogging_stdlog=$?
+if [ $no_liblogging_stdlog -ne 0 ];then
+ echo "liblogging-stdlog not available - skipping test"
+ exit 77
+fi
+
+export NUMMESSAGES=1
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+global(localHostName="rsyslog-testbench-hostname")
+
+module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off")
+input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket")
+
+template(name="outfmt" type="string" string="%hostname:%\n")
+local1.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+# the message itself is irrelevant. The only important thing is
+# there is one
+./syslog_caller -m1 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="rsyslog-testbench-hostname"
+cmp_exact
+exit_test
diff --git a/tests/imuxsock_legacy.sh b/tests/imuxsock_legacy.sh
new file mode 100755
index 0000000..e3a224f
--- /dev/null
+++ b/tests/imuxsock_legacy.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# This tests legacy syntax.
+# Added 2019-08-13 by Rainer Gerhards; released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+check_logger_has_option_d
+generate_conf
+add_conf '
+$ModLoad ../plugins/imuxsock/.libs/imuxsock
+$OmitLocalLogging on
+
+$AddUnixListenSocket '$RSYSLOG_DYNNAME'-testbench_socket
+
+template(name="outfmt" type="string" string="%msg:%\n")
+*.=notice action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+# send a message with trailing LF
+logger -d -u $RSYSLOG_DYNNAME-testbench_socket test
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=" test"
+cmp_exact
+exit_test
diff --git a/tests/imuxsock_logger.sh b/tests/imuxsock_logger.sh
new file mode 100755
index 0000000..508676f
--- /dev/null
+++ b/tests/imuxsock_logger.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+. ${srcdir:=.}/diag.sh init
+check_logger_has_option_d
+export NUMMESSAGES=1
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off")
+input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket")
+
+template(name="outfmt" type="string" string="%msg:%\n")
+*.=notice action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+logger -d -u $RSYSLOG_DYNNAME-testbench_socket test
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=" test"
+cmp_exact
+exit_test
diff --git a/tests/imuxsock_logger_err.sh b/tests/imuxsock_logger_err.sh
new file mode 100755
index 0000000..3e6c3a3
--- /dev/null
+++ b/tests/imuxsock_logger_err.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# this is primarily a safeguard to ensure the imuxsock tests basically work
+# added 2014-12-04 by Rainer Gerhards, licensed under ASL 2.0
+echo \[imuxsock_logger.sh\]: test imuxsock
+. ${srcdir:=.}/diag.sh init
+check_logger_has_option_d
+generate_conf
+add_conf '
+module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off")
+input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket")
+
+template(name="outfmt" type="string" string="%msg:%\n")
+*.=notice action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+# send a message with trailing LF
+logger -d -u $RSYSLOG_DYNNAME-testbench_socket "wrong message"
+# the sleep below is needed to prevent too-early termination of rsyslogd
+./msleep 100
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+cmp $RSYSLOG_OUT_LOG $srcdir/resultdata/imuxsock_logger.log
+if [ $? -eq 0 ]; then
+ echo "imuxsock_logger_err.sh did not report an error where it should!"
+ exit 1
+else
+ echo "all well, we saw the error that we wanted to have"
+fi;
+exit_test
diff --git a/tests/imuxsock_logger_parserchain.sh b/tests/imuxsock_logger_parserchain.sh
new file mode 100755
index 0000000..78cbd81
--- /dev/null
+++ b/tests/imuxsock_logger_parserchain.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# Copyright (C) 2015-03-04 by rainer gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+check_logger_has_option_d
+export NUMMESSAGES=1
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off")
+input( type="imuxsock" socket="'$RSYSLOG_DYNNAME'-testbench_socket"
+ useSpecialParser="off"
+ parseHostname="on")
+
+template(name="outfmt" type="string" string="%msg:%\n")
+*.=notice action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+logger -d --rfc3164 -u $RSYSLOG_DYNNAME-testbench_socket test
+if [ ! $? -eq 0 ]; then
+logger -d -u $RSYSLOG_DYNNAME-testbench_socket test
+fi;
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=" test"
+cmp_exact
+exit_test
diff --git a/tests/imuxsock_logger_ratelimit.sh b/tests/imuxsock_logger_ratelimit.sh
new file mode 100755
index 0000000..b84a790
--- /dev/null
+++ b/tests/imuxsock_logger_ratelimit.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+echo \[imuxsock_logger_ratelimit.sh\]: test rate limiting with imuxsock
+. ${srcdir:=.}/diag.sh init
+
+./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1
+no_liblogging_stdlog=$?
+if [ $no_liblogging_stdlog -ne 0 ];then
+ echo "liblogging-stdlog not available - skipping test"
+ exit 77
+fi
+
+export EXPECTED=" test message nbr 0, severity=6
+ test message nbr 1, severity=6
+ test message nbr 2, severity=6
+ test message nbr 3, severity=6
+ test message nbr 4, severity=6"
+
+for use_special_parser in on off; do
+ echo \[imuxsock_logger_ratelimit.sh\]: test rate limiting with imuxsock with useSpecialParser="$use_special_parser"
+ echo -n >"$RSYSLOG_OUT_LOG"
+ generate_conf
+ add_conf '
+ module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off")
+ input( type="imuxsock" socket="'$RSYSLOG_DYNNAME'-testbench_socket"
+ useSpecialParser="'$use_special_parser'"
+ ruleset="testruleset"
+ ratelimit.interval="10"
+ ratelimit.burst="5")
+ template(name="outfmt" type="string" string="%msg:%\n")
+
+ ruleset(name="testruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+ }
+ '
+ startup
+
+ ./syslog_caller -m20 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket" -s6
+
+ # the sleep below is needed to prevent too-early termination of rsyslogd
+ ./msleep 100
+
+ shutdown_when_empty
+ wait_shutdown
+
+ cmp_exact
+done
+exit_test
diff --git a/tests/imuxsock_logger_root.sh b/tests/imuxsock_logger_root.sh
new file mode 100755
index 0000000..b65d219
--- /dev/null
+++ b/tests/imuxsock_logger_root.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# note: we must be root and no other syslogd running in order to
+# carry out this test.
+echo \[imuxsock_logger_root.sh\]: test trailing LF handling in imuxsock
+echo This test must be run as root with no other active syslogd
+if [ "$EUID" -ne 0 ]; then
+ exit 77 # Not root, skip this test
+fi
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$ModLoad ../plugins/imuxsock/.libs/imuxsock
+
+$template outfmt,"%msg:%\n"
+*.=notice action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+# send a message with trailing LF
+logger test
+# the sleep below is needed to prevent too-early termination of rsyslogd
+./msleep 100
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+cmp $RSYSLOG_OUT_LOG $srcdir/resultdata/imuxsock_logger.log
+if [ ! $? -eq 0 ]; then
+echo "imuxsock_logger.sh failed"
+exit 1
+fi;
+exit_test
diff --git a/tests/imuxsock_logger_ruleset.sh b/tests/imuxsock_logger_ruleset.sh
new file mode 100755
index 0000000..d0c07dc
--- /dev/null
+++ b/tests/imuxsock_logger_ruleset.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# test imuxsock with ruleset definition
+# rgerhards, 2016-02-02 released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+check_logger_has_option_d
+generate_conf
+add_conf '
+module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off")
+input( type="imuxsock" socket="'$RSYSLOG_DYNNAME'-testbench_socket"
+ useSpecialParser="off"
+ ruleset="testruleset"
+ parseHostname="on")
+template(name="outfmt" type="string" string="%msg:%\n")
+
+ruleset(name="testruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+# send a message with trailing LF
+logger -d -u $RSYSLOG_DYNNAME-testbench_socket test
+# the sleep below is needed to prevent too-early termination of rsyslogd
+./msleep 100
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=" test"
+cmp_exact
+exit_test
diff --git a/tests/imuxsock_logger_ruleset_ratelimit.sh b/tests/imuxsock_logger_ruleset_ratelimit.sh
new file mode 100755
index 0000000..c13381b
--- /dev/null
+++ b/tests/imuxsock_logger_ruleset_ratelimit.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# rgerhards, 2016-02-18 released under ASL 2.0
+echo \[imuxsock_logger_ruleset_ratelimit.sh\]: test imuxsock with ruleset definition
+. ${srcdir:=.}/diag.sh init
+check_logger_has_option_d
+generate_conf
+add_conf '
+module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off")
+input( type="imuxsock" socket="'$RSYSLOG_DYNNAME'-testbench_socket"
+ useSpecialParser="off"
+ ruleset="testruleset"
+ rateLimit.Interval="2"
+ parseHostname="on")
+template(name="outfmt" type="string" string="%msg:%\n")
+
+ruleset(name="testruleset") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+# send a message with trailing LF
+logger -d -u $RSYSLOG_DYNNAME-testbench_socket test
+# the sleep below is needed to prevent too-early termination of rsyslogd
+./msleep 100
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+cmp $RSYSLOG_OUT_LOG $srcdir/resultdata/imuxsock_logger.log
+ echo \"$(cat $RSYSLOG_OUT_LOG)\"
+if [ ! $? -eq 0 ]; then
+ echo "imuxsock_logger.sh failed"
+ echo "contents of $RSYSLOG_OUT_LOG:"
+ echo \"$(cat $RSYSLOG_OUT_LOG)\"
+ exit 1
+fi;
+exit_test
diff --git a/tests/imuxsock_logger_syssock.sh b/tests/imuxsock_logger_syssock.sh
new file mode 100755
index 0000000..840b5f8
--- /dev/null
+++ b/tests/imuxsock_logger_syssock.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# test trailing LF handling in imuxsock
+# note: we use the system socket, but assign a different name to
+# it. This is not 100% the same thing as running as root, but it
+# is pretty close to it. -- rgerhards, 201602-19
+. ${srcdir:=.}/diag.sh init
+check_logger_has_option_d
+export NUMMESSAGES=1
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imuxsock/.libs/imuxsock"
+ SysSock.name="'$RSYSLOG_DYNNAME'-testbench_socket")
+
+$template outfmt,"%msg:%\n"
+*.=notice action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+logger -d -u $RSYSLOG_DYNNAME-testbench_socket test
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=" test"
+cmp_exact
+exit_test
diff --git a/tests/imuxsock_traillf.sh b/tests/imuxsock_traillf.sh
new file mode 100755
index 0000000..5b822c4
--- /dev/null
+++ b/tests/imuxsock_traillf.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1
+no_liblogging_stdlog=$?
+if [ $no_liblogging_stdlog -ne 0 ];then
+ echo "liblogging-stdlog not available - skipping test"
+ exit 77
+fi
+generate_conf
+add_conf '
+module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off")
+input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket")
+
+template(name="outfmt" type="string" string="%msg:%\n")
+local1.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+./syslog_caller -fsyslog_inject-l -m1 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=" test"
+cmp_exact
+exit_test
diff --git a/tests/imuxsock_traillf_root.sh b/tests/imuxsock_traillf_root.sh
new file mode 100755
index 0000000..efe5217
--- /dev/null
+++ b/tests/imuxsock_traillf_root.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# note: we must be root and no other syslogd running in order to
+# carry out this test
+echo \[imuxsock_traillf_root.sh\]: test trailing LF handling in imuxsock
+echo This test must be run as root with no other active syslogd
+if [ "$EUID" -ne 0 ]; then
+ exit 77 # Not root, skip this test
+fi
+./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1
+no_liblogging_stdlog=$?
+if [ $no_liblogging_stdlog -ne 0 ];then
+ echo "liblogging-stdlog not available - skipping test"
+ exit 77
+fi
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$ModLoad ../plugins/imuxsock/.libs/imuxsock
+
+$template outfmt,"%msg:%\n"
+local1.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+# send a message with trailing LF
+./syslog_caller -fsyslog_inject-l -m1
+# the sleep below is needed to prevent too-early termination of rsyslogd
+./msleep 100
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+cmp $RSYSLOG_OUT_LOG $srcdir/resultdata/imuxsock_traillf.log
+if [ ! $? -eq 0 ]; then
+echo "imuxsock_traillf_root.sh failed"
+exit 1
+fi;
+exit_test
diff --git a/tests/imuxsock_traillf_syssock.sh b/tests/imuxsock_traillf_syssock.sh
new file mode 100755
index 0000000..4d6e4e4
--- /dev/null
+++ b/tests/imuxsock_traillf_syssock.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test does not work on Solaris"
+
+./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1
+no_liblogging_stdlog=$?
+if [ $no_liblogging_stdlog -ne 0 ];then
+ echo "liblogging-stdlog not available - skipping test"
+ exit 77
+fi
+
+export NUMMESSAGES=1
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imuxsock/.libs/imuxsock"
+ SysSock.name="'$RSYSLOG_DYNNAME'-testbench_socket")
+
+template(name="outfmt" type="string" string="%msg:%\n")
+local1.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+./syslog_caller -fsyslog_inject-l -m1 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=" test"
+cmp_exact
diff --git a/tests/incltest.sh b/tests/incltest.sh
new file mode 100755
index 0000000..71b230e
--- /dev/null
+++ b/tests/incltest.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf "\$IncludeConfig ${srcdir}/testsuites/incltest.d/include.conf
+"
+startup
+# 100 messages are enough - the question is if the include is read ;)
+injectmsg 0 100
+shutdown_when_empty
+wait_shutdown
+seq_check 0 99
+exit_test
diff --git a/tests/incltest_dir.sh b/tests/incltest_dir.sh
new file mode 100755
index 0000000..80da54d
--- /dev/null
+++ b/tests/incltest_dir.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+. ${srcdir:=.}/diag.sh init
+generate_conf
+env|grep src
+echo ac_top_srcdir: $ac_top_srcdir
+echo FULL ENV:
+env
+echo FS info:
+set -x
+pwd
+echo "srcdir: $srcdir"
+ls -l ${srcdir}/testsuites/incltest.d/
+ls -l ${srcdir}/testsuites
+find ../../../.. -name incltest.d
+set +x
+add_conf "\$IncludeConfig ${srcdir}/testsuites/incltest.d/
+"
+startup
+# 100 messages are enough - the question is if the include is read ;)
+injectmsg 0 100
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 99
+exit_test
diff --git a/tests/incltest_dir_empty_wildcard.sh b/tests/incltest_dir_empty_wildcard.sh
new file mode 100755
index 0000000..51e2ac1
--- /dev/null
+++ b/tests/incltest_dir_empty_wildcard.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# This test checks if an empty includeConfig directory causes problems. It
+# should not, as this is a valid situation that by default exists on many
+# distros.
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf "\$IncludeConfig ${srcdir}/testsuites/incltest.d/*.conf-not-there
+"
+add_conf '$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")'
+startup
+# 100 messages are enough - the question is if the include is read ;)
+injectmsg 0 100
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 99
+exit_test
diff --git a/tests/incltest_dir_wildcard.sh b/tests/incltest_dir_wildcard.sh
new file mode 100755
index 0000000..376ab4e
--- /dev/null
+++ b/tests/incltest_dir_wildcard.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf "include(file=\"${srcdir}/testsuites/incltest.d/*.conf\")
+"
+startup
+# 100 messages are enough - the question is if the include is read ;)
+injectmsg 0 100
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 99
+exit_test
diff --git a/tests/include-obj-in-if-vg.sh b/tests/include-obj-in-if-vg.sh
new file mode 100755
index 0000000..39c8fb3
--- /dev/null
+++ b/tests/include-obj-in-if-vg.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum:" then {
+ include(file="'${srcdir}'/testsuites/include-std-omfile-actio*.conf")
+ continue
+}
+'
+startup_vg
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+seq_check 0 9
+exit_test
diff --git a/tests/include-obj-outside-control-flow-vg.sh b/tests/include-obj-outside-control-flow-vg.sh
new file mode 100755
index 0000000..4d4eb9f
--- /dev/null
+++ b/tests/include-obj-outside-control-flow-vg.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if not ($msg contains "msgnum:") then {
+ stop
+}
+
+# Note: the point of this test is to have this include outside of
+# a control flow construct -- this the "strange" if above.'
+add_conf "
+include(file=\"${srcdir}/testsuites/include-std-omfile-actio*.conf\")
+"
+startup_vg
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+seq_check 0 9
+exit_test
diff --git a/tests/include-obj-text-from-file-noexist.sh b/tests/include-obj-text-from-file-noexist.sh
new file mode 100755
index 0000000..cc1b3e6
--- /dev/null
+++ b/tests/include-obj-text-from-file-noexist.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+if $msg contains "msgnum:" then {
+ include(text=`cat '${srcdir}'/testsuites/DOES-NOT-EXIST`)
+}
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex 'file could not be accessed for `cat .*/testsuites/DOES-NOT-EXIST'
+exit_test
diff --git a/tests/include-obj-text-from-file.sh b/tests/include-obj-text-from-file.sh
new file mode 100755
index 0000000..10c613e
--- /dev/null
+++ b/tests/include-obj-text-from-file.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum:" then {'
+add_conf "
+ include(text=\`cat ${srcdir}/testsuites/include-std-omfile-action.conf\`)
+}
+"
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+seq_check 0 9
+exit_test
diff --git a/tests/include-obj-text-vg.sh b/tests/include-obj-text-vg.sh
new file mode 100755
index 0000000..fd929b6
--- /dev/null
+++ b/tests/include-obj-text-vg.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+INCLFILE="${srcdir}/testsuites/include-std-omfile-action.conf"
+export CONF_SNIPPET=`cat $INCLFILE`
+printf "\nThis SNIPPET will be included via env var:\n$CONF_SNIPPET\n\nEND SNIPPET\n"
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum:" then {
+ include(text=`echo $CONF_SNIPPET`)
+}
+'
+startup_vg
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+seq_check 0 9
+exit_test
diff --git a/tests/inputfilegen.c b/tests/inputfilegen.c
new file mode 100644
index 0000000..b4e9c2d
--- /dev/null
+++ b/tests/inputfilegen.c
@@ -0,0 +1,234 @@
+/* generate an input file suitable for use by the testbench
+ * Copyright (C) 2018-2022 by Rainer Gerhards and Adiscon GmbH.
+ * Copyright (C) 2016-2018 by Pascal Withopf and Adiscon GmbH.
+ *
+ * usage: ./inputfilegen num-lines > file
+ * -m number of messages
+ * -i start number of message
+ * -d extra data to add (all 'X' after the msgnum)
+ * -s size of file to generate
+ * cannot be used together with -m
+ * size may be slightly smaller in order to be able to write
+ * the last complete line.
+ * -M "message count file" - contains number of messages to be written
+ * This is especially useful with -s, as the testbench otherwise does
+ * not know how to do a seq_check. To keep things flexible, can also be
+ * used with -m (this may aid testbench framework generalization).
+ * -f outputfile
+ * Permits to write data to file "outputfile" instead of stdout. Also
+ * enables support for SIGHUP.
+ * -S sleep time
+ * ms to sleep between sending message bulks (bulks size given by -B)
+ * -B number of messages in bulk
+ * number of messages to send without sleeping as specified in -S.
+ * IGNORED IF -S is not also given!
+ * Part of rsyslog, licensed under ASL 2.0
+ */
+#include "config.h"
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#if defined(_AIX)
+ #include <unistd.h>
+#else
+ #include <getopt.h>
+#endif
+#if defined(__FreeBSD__)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#if defined(HAVE_SYS_SELECT_H)
+#include <sys/select.h>
+#endif
+
+#define DEFMSGS 5
+#define NOEXTRADATA -1
+
+static volatile int bHadHUP = 0;
+static void
+hdlr_sighup(int sig)
+{
+ fprintf(stderr, "inputfilegen: had hup, sig %d\n", sig);
+ bHadHUP = 1;
+}
+static void
+sighup_enable()
+{
+ struct sigaction sigAct;
+ memset(&sigAct, 0, sizeof (sigAct));
+ sigemptyset(&sigAct.sa_mask);
+ sigAct.sa_handler = hdlr_sighup;
+ sigaction(SIGHUP, &sigAct, NULL);
+}
+
+void msleep(const int sleepTime)
+{
+ struct timeval tvSelectTimeout;
+
+ tvSelectTimeout.tv_sec = sleepTime / 1000;
+ tvSelectTimeout.tv_usec = (sleepTime % 1000) * 1000; /* micro seconds */
+ if(select(0, NULL, NULL, NULL, &tvSelectTimeout) == -1) {
+ if(errno != EINTR) {
+ perror("select");
+ exit(1);
+ }
+ }
+}
+
+static FILE *
+open_output(const char *fn)
+{
+ FILE *fh_output = fopen(fn, "w");
+ if(fh_output == NULL) {
+ perror(fn);
+ exit(1);
+ }
+ return fh_output;
+}
+
+int main(int argc, char* argv[])
+{
+ int c, i;
+ long long nmsgs = DEFMSGS;
+ long long nmsgstart = 0;
+ int nfinishedidle = 0;
+ int nchars = NOEXTRADATA;
+ int errflg = 0;
+ long long filesize = -1;
+ char *extradata = NULL;
+ const char *msgcntfile = NULL;
+ const char *outputfile = "-";
+ FILE *fh_output;
+ int sleep_ms = 0; /* How long to sleep between message writes */
+ int sleep_msgs = 0; /* messages to xmit between sleeps (if configured) */
+ int sleep_hubreopen_ms = 5; /* Wait until new file is being reopened, logrotate may need some time */
+ int ctr = 0;
+
+ while((c=getopt(argc, argv, "m:M:i:I:h:d:s:f:S:B:")) != -1) {
+ switch(c) {
+ case 'm':
+ nmsgs = atoi(optarg);
+ break;
+ case 'M':
+ msgcntfile = optarg;
+ break;
+ case 'i':
+ nmsgstart = atoi(optarg);
+ break;
+ case 'I':
+ nfinishedidle = atoi(optarg);
+ break;
+ case 'd':
+ nchars = atoi(optarg);
+ break;
+ case 's':
+ filesize = atoll(optarg);
+ break;
+ case 'S':
+ sleep_ms = atoi(optarg);
+ break;
+ case 'B':
+ sleep_msgs = atoi(optarg);
+ break;
+ case 'h':
+ sleep_hubreopen_ms = atoi(optarg);
+ break;
+ case 'f':
+ outputfile = optarg;
+ sighup_enable();
+ break;
+ case ':':
+ fprintf(stderr, "Option -%c requires an operand\n", optopt);
+ errflg++;
+ break;
+ case '?':
+ fprintf(stderr, "inputfilegen: Unrecognized option: -%c\n", optopt);
+ errflg++;
+ break;
+ }
+ }
+ if(errflg) {
+ fprintf(stderr, "invalid call\n");
+ exit(2);
+ }
+
+ if(filesize != -1) {
+ const int linesize = (17 + nchars); /* 17 is std line size! */
+ nmsgs = filesize / linesize;
+ fprintf(stderr, "inputfilegen: file size requested %lld, actual %lld with "
+ "%lld lines, %lld bytes less\n",
+ filesize, nmsgs * linesize, nmsgs, filesize - nmsgs * linesize);
+ if(nmsgs > 100000000) {
+ fprintf(stderr, "inputfilegen: number of lines exhaust 8-digit line numbers "
+ "which are standard inside the testbench.\n"
+ "Use -d switch to add extra data (e.g. -d111 for "
+ "128 byte lines or -d47 for 64 byte lines)\n");
+ exit(1);
+ }
+ }
+
+ if(msgcntfile != NULL) {
+ FILE *const fh = fopen(msgcntfile, "w");
+ if(fh == NULL) {
+ perror(msgcntfile);
+ exit(1);
+ }
+ fprintf(fh, "%lld", nmsgs);
+ fclose(fh);
+ }
+
+ if(strcmp(outputfile, "-")) {
+ fh_output = open_output(outputfile);
+ } else {
+ fh_output = stdout;
+ }
+
+ if(nchars != NOEXTRADATA) {
+ extradata = (char *)malloc(nchars + 1);
+ memset(extradata, 'X', nchars);
+ extradata[nchars] = '\0';
+ }
+ for(i = nmsgstart; i < (nmsgs+nmsgstart); ++i) {
+ if( sleep_ms > 0 &&
+ ctr++ >= sleep_msgs) {
+ msleep(sleep_ms);
+ ctr = 0;
+ }
+ if(bHadHUP) {
+ fclose(fh_output);
+ if(sleep_hubreopen_ms > 0) {
+ /* Extra Sleep so logrotate or whatever can take place */
+ msleep(sleep_hubreopen_ms);
+ }
+ fh_output = open_output(outputfile);
+ fprintf(stderr, "inputfilegen: %s reopened\n", outputfile);
+ fprintf(stderr, "inputfilegen: current message number %d\n", i);
+ bHadHUP = 0;
+ }
+ fprintf(fh_output, "msgnum:%8.8d:", i);
+ if(nchars != NOEXTRADATA) {
+ fprintf(fh_output, "%s", extradata);
+ }
+ fprintf(fh_output, "\n");
+ }
+ if (nfinishedidle > 0) {
+ /* Keep process open for nfinishedidle ms */
+ for(int x = 0; x < nfinishedidle; ++x) {
+ if(bHadHUP) {
+ /* Create empty file */
+ fh_output = open_output(outputfile);
+ fclose(fh_output);
+ fprintf(stderr, "inputfilegen: last message number was %d\n", i);
+ bHadHUP = 0;
+ }
+ msleep(1);
+ }
+ }
+
+ free(extradata);
+ return 0;
+}
diff --git a/tests/inputname-imtcp.sh b/tests/inputname-imtcp.sh
new file mode 100755
index 0000000..bd30a1e
--- /dev/null
+++ b/tests/inputname-imtcp.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1" name="l1")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port2" ruleset="ruleset1" name="l2")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port3" ruleset="ruleset1" name="l3")
+
+template(name="outfmt" type="string" string="%inputname%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+
+'
+startup
+assign_tcpflood_port2 "$RSYSLOG_DYNNAME.tcpflood_port2"
+assign_rs_port "$RSYSLOG_DYNNAME.tcpflood_port3"
+tcpflood -p $TCPFLOOD_PORT -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: MSG\""
+tcpflood -p $TCPFLOOD_PORT2 -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: MSG\""
+tcpflood -p $RS_PORT -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: MSG\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='l1
+l2
+l3'
+cmp_exact
+exit_test
diff --git a/tests/internal-errmsg-memleak-vg.sh b/tests/internal-errmsg-memleak-vg.sh
new file mode 100755
index 0000000..adc0c2a
--- /dev/null
+++ b/tests/internal-errmsg-memleak-vg.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# This tests a memory leak we have seen when processing internal error
+# message with the settings used in this test. We use imfile as it is
+# easist to reproduce this way. Note that we are only interested in
+# whether or not we have a leak, not any other functionality. Most
+# importantly, we do not care if the error message appears or not. This
+# is because it is not so easy to pick it up from the system log and other
+# tests already cover this scenario.
+# add 2017-05-10 by Rainer Gerhards, released under ASL 2.0
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(processInternalMessages="off")
+$RepeatedMsgReduction on # keep this on because many distros have set it
+
+module(load="../plugins/imfile/.libs/imfile") # mode="polling" pollingInterval="1")
+input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="tag1" ruleset="ruleset1")
+
+template(name="tmpl1" type="string" string="%msg%\n")
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="tmpl1")
+}
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)
+'
+startup_vg_waitpid_only
+./msleep 500 # wait a bit so that the error message can be emitted
+shutdown_immediate
+wait_shutdown_vg
+
+exit_test
diff --git a/tests/invalid_nested_include.sh b/tests/invalid_nested_include.sh
new file mode 100755
index 0000000..491ef1e
--- /dev/null
+++ b/tests/invalid_nested_include.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Note: this test tests if we die when recursively include the same
+# file ever again. This is a user error, but we should detect it.
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+echo '$IncludeConfig '${RSYSLOG_DYNNAME}'work-nested.conf
+' > ${RSYSLOG_DYNNAME}work-nested.conf
+add_conf '
+$IncludeConfig '${RSYSLOG_DYNNAME}'work-nested.conf
+template(name="outfmt" type="string" string="%msg%\n")
+if $msg contains "error" then
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+shutdown_when_empty
+wait_shutdown
+grep ${RSYSLOG_DYNNAME}work-nested.conf $RSYSLOG_OUT_LOG
+if [ $? -ne 0 ]; then
+ echo "FAIL: $RSYSLOG_OUT_LOG does not contain expected error message on"
+ echo "recursive include file ${RSYSLOG_DYNNAME}work-nested.conf."
+ echo "content is:"
+ echo "......................................................................"
+ cat $RSYSLOG_OUT_LOG
+ echo "......................................................................"
+ error_exit
+fi
+exit_test
diff --git a/tests/journal_print.c b/tests/journal_print.c
new file mode 100644
index 0000000..4336e29
--- /dev/null
+++ b/tests/journal_print.c
@@ -0,0 +1,68 @@
+/* A testing tool that tries to emit message given as argument
+ * to the journal, and, if succceds (at least per journald retcode).
+ * If whole operation is successful there is need to actually check
+ * that message is present in journal (also veryfing journal read perms)
+ *
+ * Retcodes: 0 - success
+ * 1 - wrong arguments (expects exactly one)
+ * 2 - failed to open journal for writing
+ * 3 - failed to actually write message to journal
+ *
+ * Part of the testbench for rsyslog.
+ *
+ * Copyright 2018 Red Hat Inc.
+ *
+ * This file is part of rsyslog.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * -or-
+ * see COPYING.ASL20 in the source distribution
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <systemd/sd-journal.h>
+
+int main(int argc, char *argv[])
+{
+ if(argc != 2) {
+ fprintf(stderr, "usage: journal_print \"message\"\n");
+ exit(1);
+ }
+
+ /* First, we need to determine whether journal is running at all */
+ int fd;
+ FILE *log;
+ fd = sd_journal_stream_fd("imjournal_test", LOG_WARNING, 0);
+ if (fd < 0) {
+ fprintf(stderr, "Failed to create journal fd: %s\n", strerror(-fd));
+ exit(2);
+ }
+ log = fdopen(fd, "w");
+ if (!log) {
+ fprintf(stderr, "Failed to create file object: %m\n");
+ close(fd);
+ exit(2);
+ }
+
+ /* Now we can try inserting something */
+ if (fprintf(log, "%s", argv[1]) <= 0) {
+ fprintf(stderr, "Failed to write to journal log: %m\n");
+ close(fd);
+ exit(3);
+ }
+
+ return(0);
+}
diff --git a/tests/json-nonstring.sh b/tests/json-nonstring.sh
new file mode 100755
index 0000000..cda1100
--- /dev/null
+++ b/tests/json-nonstring.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# written 2019-05-10 by Rainer Gerhards
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="json" type="list" option.jsonf="on") {
+ property(outname="number_0" format="jsonf" name="$!val0" datatype="number")
+ property(outname="bool_0" format="jsonf" name="$!val0" datatype="bool")
+
+ property(outname="empty" format="jsonf" name="$!empty" datatype="auto")
+ property(outname="empty_skip" format="jsonf" name="$!empty" onEmpty="skip")
+ property(outname="empty_null" format="jsonf" name="$!empty" onEmpty="null")
+ property(outname="empty_number" format="jsonf" name="$!empty" datatype="number")
+
+ property(outname="auto_string" format="jsonf" name="$!string" datatype="auto")
+
+ property(outname="auto" format="jsonf" name="$!val" datatype="auto" onEmpty="null")
+ property(outname="number" format="jsonf" name="$!val" datatype="number")
+ property(outname="bool" format="jsonf" name="$!val" datatype="bool")
+ property(outname="string" format="jsonf" name="$!val" datatype="string")
+ property(outname="no_datatype" format="jsonf" name="$!val")
+}
+
+set $!val0 = 0;
+set $!val = 42;
+set $!empty = "";
+set $!string = "1.2.3.4";
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="json")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check '{"number_0":0, "bool_0":false, "empty":"", "empty_null":null, "empty_number":0, "auto_string":"1.2.3.4", "auto":42, "number":42, "bool":true, "string":"42", "no_datatype":"42"}'
+check_not_present 'empty_skip'
+exit_test
diff --git a/tests/json-onempty-at-end.sh b/tests/json-onempty-at-end.sh
new file mode 100755
index 0000000..a03cc20
--- /dev/null
+++ b/tests/json-onempty-at-end.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# written 2019-05-10 by Rainer Gerhards
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="json" type="list" option.jsonf="on") {
+ property(outname="empty_null" format="jsonf" name="$!empty" onEmpty="null")
+ property(outname="empty_skip" format="jsonf" name="$!empty" onEmpty="skip")
+}
+
+set $!val0 = 0;
+set $!val = 42;
+set $!empty = "";
+set $!string = "1.2.3.4";
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="json")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check '{"empty_null":null}'
+check_not_present 'empty_skip'
+exit_test
diff --git a/tests/json_array_looping-vg.sh b/tests/json_array_looping-vg.sh
new file mode 100755
index 0000000..84cdabe
--- /dev/null
+++ b/tests/json_array_looping-vg.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+# added 2016-03-31 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[json_array_looping-vg.sh\]: basic test for looping over json array with valgrind
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="garply" type="string" string="garply: %$.garply%\n")
+template(name="grault" type="string" string="grault: %$.grault%\n")
+template(name="prefixed_grault" type="string" string="prefixed_grault: %$.grault%\n")
+template(name="quux" type="string" string="quux: %$.quux%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse")
+set $.garply = "";
+
+ruleset(name="prefixed_writer" queue.type="linkedlist" queue.workerthreads="5") {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.prefixed.log" template="prefixed_grault" queue.type="linkedlist")
+}
+
+foreach ($.quux in $!foo) do {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="quux")
+ foreach ($.corge in $.quux!bar) do {
+ reset $.grault = $.corge;
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.async.log" template="grault" queue.type="linkedlist" action.copyMsg="on")
+ call prefixed_writer
+ if ($.garply != "") then
+ set $.garply = $.garply & ", ";
+ reset $.garply = $.garply & $.grault!baz;
+ }
+}
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="garply")
+'
+startup_vg
+tcpflood -m 1 -I $srcdir/testsuites/json_array_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+content_check 'quux: abc0'
+content_check 'quux: def1'
+content_check 'quux: ghi2'
+content_check 'quux: { "bar": [ { "baz": "important_msg" }, { "baz": "other_msg" } ] }'
+custom_content_check 'grault: { "baz": "important_msg" }' $RSYSLOG_DYNNAME.out.async.log
+custom_content_check 'grault: { "baz": "other_msg" }' $RSYSLOG_DYNNAME.out.async.log
+custom_content_check 'prefixed_grault: { "baz": "important_msg" }' $RSYSLOG_DYNNAME.out.prefixed.log
+custom_content_check 'prefixed_grault: { "baz": "other_msg" }' $RSYSLOG_DYNNAME.out.prefixed.log
+content_check 'garply: important_msg, other_msg'
+exit_test
diff --git a/tests/json_array_looping.sh b/tests/json_array_looping.sh
new file mode 100755
index 0000000..b2e9790
--- /dev/null
+++ b/tests/json_array_looping.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# added 2014-11-11 by singh.janmejay
+# basic test for looping over json array
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="garply" type="string" string="garply: %$.garply%\n")
+template(name="grault" type="string" string="grault: %$.grault%\n")
+template(name="prefixed_grault" type="string" string="prefixed_grault: %$.grault%\n")
+template(name="quux" type="string" string="quux: %$.quux%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse")
+set $.garply = "";
+
+ruleset(name="prefixed_writer" queue.type="linkedlist" queue.workerthreads="5") {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.prefixed.log" template="prefixed_grault" queue.type="linkedlist")
+}
+
+foreach ($.quux in $!foo) do {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="quux")
+ foreach ($.corge in $.quux!bar) do {
+ reset $.grault = $.corge;
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.async.log" template="grault" queue.type="linkedlist" action.copyMsg="on")
+ call prefixed_writer
+ if ($.garply != "") then
+ set $.garply = $.garply & ", ";
+ reset $.garply = $.garply & $.grault!baz;
+ }
+}
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="garply")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/json_array_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check 'quux: abc0'
+content_check 'quux: def1'
+content_check 'quux: ghi2'
+content_check 'quux: { "bar": [ { "baz": "important_msg" }, { "baz": "other_msg" } ] }'
+custom_content_check 'grault: { "baz": "important_msg" }' $RSYSLOG_DYNNAME.out.async.log
+custom_content_check 'grault: { "baz": "other_msg" }' $RSYSLOG_DYNNAME.out.async.log
+custom_content_check 'prefixed_grault: { "baz": "important_msg" }' $RSYSLOG_DYNNAME.out.prefixed.log
+custom_content_check 'prefixed_grault: { "baz": "other_msg" }' $RSYSLOG_DYNNAME.out.prefixed.log
+content_check 'garply: important_msg, other_msg'
+exit_test
diff --git a/tests/json_array_subscripting.sh b/tests/json_array_subscripting.sh
new file mode 100755
index 0000000..2c01d2a
--- /dev/null
+++ b/tests/json_array_subscripting.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2014-11-11 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[json_array_subscripting.sh\]: basic test for json array subscripting
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="msg: %$!foo[1]% | %$.quux% | %$.corge% | %$.grault% | %$!foo[3]!bar[1]!baz%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse")
+set $.quux = $!foo[2];
+set $.corge = $!foo[3]!bar[0]!baz;
+set $.grault = $!foo[3]!bar[1];
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/json_array_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check 'msg: def1 | ghi2 | important_msg | { "baz": "other_msg" } | other_msg'
+exit_test
diff --git a/tests/json_nonarray_looping.sh b/tests/json_nonarray_looping.sh
new file mode 100755
index 0000000..a38b243
--- /dev/null
+++ b/tests/json_nonarray_looping.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# added 2015-03-02 by singh.janmejay
+# test to assert attempt to iterate upon a non-array json-object fails gracefully
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="garply" type="string" string="garply: %$.garply%\n")
+template(name="grault" type="string" string="grault: %$.grault%\n")
+template(name="prefixed_grault" type="string" string="prefixed_grault: %$.grault%\n")
+template(name="quux" type="string" string="quux: %$.quux%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse")
+set $.garply = "";
+
+ruleset(name="prefixed_writer" queue.type="linkedlist" queue.workerthreads="5") {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.prefixed.log" template="prefixed_grault" queue.type="linkedlist")
+}
+
+foreach ($.quux in $!foo) do {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="quux")
+ foreach ($.corge in $.quux!bar) do {
+ reset $.grault = $.corge;
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.async.log" template="grault" queue.type="linkedlist" action.copyMsg="on")
+ call prefixed_writer
+ if ($.garply != "") then
+ set $.garply = $.garply & ", ";
+ reset $.garply = $.garply & $.grault!baz;
+ }
+}
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="garply")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/json_nonarray_input
+shutdown_when_empty
+wait_shutdown
+assert_content_missing 'quux'
+exit_test
diff --git a/tests/json_null-vg.sh b/tests/json_null-vg.sh
new file mode 100755
index 0000000..cd6e353
--- /dev/null
+++ b/tests/json_null-vg.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# added 2015-11-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+# Note: the aim of this test is to test against misaddressing, so we do
+# not actually check the output
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[json_null.sh\]: test for json containing \"null\" value
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# we must make sure the template contains a reference to the
+# data item with null value
+template(name="outfmt" type="string" string="%$!nope%\n")
+template(name="outfmt-all-json" type="string" string="%$!all-json%\n")
+
+action(type="mmjsonparse")
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+if $!nope == "" then
+ action(type="omfile" file="./'"${RSYSLOG2_OUT_LOG}"'" template="outfmt-all-json")
+'
+startup_vg
+tcpflood -m 1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 test: @cee: { \\\"nope\\\": null }\""
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+exit_test
diff --git a/tests/json_null.sh b/tests/json_null.sh
new file mode 100755
index 0000000..a7f9413
--- /dev/null
+++ b/tests/json_null.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# added 2015-11-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+# Note: the aim of this test is to test against misaddressing, so we do
+# not actually check the output
+echo ===============================================================================
+echo \[json_null.sh\]: test for json containing \"null\" value
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# we must make sure the template contains a reference to the
+# data item with null value
+template(name="outfmt" type="string" string="%$!nope%\n")
+template(name="outfmt-all-json" type="string" string="%$!all-json%\n")
+
+action(type="mmjsonparse")
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+if $!nope == "" then
+ action(type="omfile" file="./'"${RSYSLOG2_OUT_LOG}"'" template="outfmt-all-json")
+'
+startup
+tcpflood -m 1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 test: @cee: { \\\"nope\\\": null }\""
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+exit_test
diff --git a/tests/json_null_array-vg.sh b/tests/json_null_array-vg.sh
new file mode 100755
index 0000000..b8ee197
--- /dev/null
+++ b/tests/json_null_array-vg.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# added 2015-11-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[json_null_array.sh\]: test for json containing \"null\" value
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%$.data%\n")
+
+action(type="mmjsonparse")
+foreach ($.data in $!array) do {
+ if not ($.data == "") then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup_vg
+tcpflood -m 1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 test: @cee: { \\\"array\\\": [0, 1, null, 2, 3, null, 4] }\""
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+seq_check 0 4
+exit_test
diff --git a/tests/json_null_array.sh b/tests/json_null_array.sh
new file mode 100755
index 0000000..8ee8a48
--- /dev/null
+++ b/tests/json_null_array.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2015-11-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[json_null_array.sh\]: test for json containing \"null\" value
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%$.data%\n")
+
+action(type="mmjsonparse")
+foreach ($.data in $!array) do {
+ if not ($.data == "") then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -m 1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 test: @cee: { \\\"array\\\": [0, 1, null, 2, 3, null, 4] }\""
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4
+exit_test
diff --git a/tests/json_object_looping-vg.sh b/tests/json_object_looping-vg.sh
new file mode 100755
index 0000000..2ebbefe
--- /dev/null
+++ b/tests/json_object_looping-vg.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+# added 2016-03-31 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[json_object_looping-vg.sh\]: basic test for looping over json object / associative-array with valgrind
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="garply" type="string" string="garply: %$.garply%\n")
+template(name="corge" type="string" string="corge: key: %$.corge!key% val: %$.corge!value%\n")
+template(name="prefixed_corge" type="string" string="prefixed_corge: %$.corge%\n")
+template(name="quux" type="string" string="quux: %$.quux%\n")
+template(name="modified" type="string" string="new: %$!foo!str4% deleted: %$!foo!str3%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse")
+set $.garply = "";
+
+ruleset(name="prefixed_writer" queue.type="linkedlist" queue.workerthreads="5") {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.prefixed.log" template="prefixed_corge" queue.type="linkedlist")
+}
+
+foreach ($.quux in $!foo) do {
+ if ($.quux!key == "str2") then {
+ set $.quux!random_key = $.quux!key;
+ unset $!foo!str3; #because it is deep copied, the foreach loop will still see str3, but the "modified" action in the bottom will not
+ set $!foo!str4 = "jkl3";
+ }
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="quux")
+ foreach ($.corge in $.quux!value) do {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.async.log" template="corge" queue.type="linkedlist" action.copyMsg="on")
+ call prefixed_writer
+
+ foreach ($.grault in $.corge!value) do {
+ if ($.garply != "") then
+ set $.garply = $.garply & ", ";
+ set $.garply = $.garply & $.grault!key & "=" & $.grault!value;
+ }
+ }
+}
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="garply")
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="modified")
+'
+startup_vg
+tcpflood -m 1 -I $srcdir/testsuites/json_object_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+content_check 'quux: { "key": "str1", "value": "abc0" }'
+content_check 'quux: { "key": "str2", "value": "def1", "random_key": "str2" }'
+content_check 'quux: { "key": "str3", "value": "ghi2" }'
+assert_content_missing 'quux: { "key": "str4", "value": "jkl3" }'
+content_check 'new: jkl3'
+assert_content_missing 'deleted: ghi2'
+content_check 'quux: { "key": "obj", "value": { "bar": { "k1": "important_msg", "k2": "other_msg" } } }'
+custom_content_check 'corge: key: bar val: { "k1": "important_msg", "k2": "other_msg" }' $RSYSLOG_DYNNAME.out.async.log
+custom_content_check 'prefixed_corge: { "key": "bar", "value": { "k1": "important_msg", "k2": "other_msg" } }' $RSYSLOG_DYNNAME.out.prefixed.log
+content_check 'garply: k1=important_msg, k2=other_msg'
+exit_test
diff --git a/tests/json_object_looping.sh b/tests/json_object_looping.sh
new file mode 100755
index 0000000..2f0cd03
--- /dev/null
+++ b/tests/json_object_looping.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# added 2016-03-31 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[json_object_looping.sh\]: basic test for looping over json object / associative-array
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="garply" type="string" string="garply: %$.garply%\n")
+template(name="corge" type="string" string="corge: key: %$.corge!key% val: %$.corge!value%\n")
+template(name="prefixed_corge" type="string" string="prefixed_corge: %$.corge%\n")
+template(name="quux" type="string" string="quux: %$.quux%\n")
+template(name="modified" type="string" string="new: %$!foo!str4% deleted: %$!foo!str3%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse")
+set $.garply = "";
+
+ruleset(name="prefixed_writer" queue.type="linkedlist" queue.workerthreads="5") {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.prefixed.log" template="prefixed_corge" queue.type="linkedlist")
+}
+
+foreach ($.quux in $!foo) do {
+ if ($.quux!key == "str2") then {
+ set $.quux!random_key = $.quux!key;
+ unset $!foo!str3; #because it is deep copied, the foreach loop will still see str3, but the "modified" action in the bottom will not
+ set $!foo!str4 = "jkl3";
+ }
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="quux")
+ foreach ($.corge in $.quux!value) do {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.async.log" template="corge" queue.type="linkedlist" action.copyMsg="on")
+ call prefixed_writer
+
+ foreach ($.grault in $.corge!value) do {
+ if ($.garply != "") then
+ set $.garply = $.garply & ", ";
+ set $.garply = $.garply & $.grault!key & "=" & $.grault!value;
+ }
+ }
+}
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="garply")
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="modified")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/json_object_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check 'quux: { "key": "str1", "value": "abc0" }'
+content_check 'quux: { "key": "str2", "value": "def1", "random_key": "str2" }'
+content_check 'quux: { "key": "str3", "value": "ghi2" }'
+assert_content_missing 'quux: { "key": "str4", "value": "jkl3" }'
+content_check 'new: jkl3'
+assert_content_missing 'deleted: ghi2'
+content_check 'quux: { "key": "obj", "value": { "bar": { "k1": "important_msg", "k2": "other_msg" } } }'
+custom_content_check 'corge: key: bar val: { "k1": "important_msg", "k2": "other_msg" }' $RSYSLOG_DYNNAME.out.async.log
+custom_content_check 'prefixed_corge: { "key": "bar", "value": { "k1": "important_msg", "k2": "other_msg" } }' $RSYSLOG_DYNNAME.out.prefixed.log
+content_check 'garply: k1=important_msg, k2=other_msg'
+exit_test
diff --git a/tests/json_object_suicide_in_loop-vg.sh b/tests/json_object_suicide_in_loop-vg.sh
new file mode 100755
index 0000000..cccb4cb
--- /dev/null
+++ b/tests/json_object_suicide_in_loop-vg.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# basic test for looping over json object and unsetting it while inside the loop-body
+# added 2016-03-31 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+generate_conf
+add_conf '
+template(name="corge" type="string" string="corge: key: %$.corge!key% val: %$.corge!value%\n")
+template(name="quux" type="string" string="quux: %$.quux%\n")
+template(name="post_suicide_foo" type="string" string="post_suicide_foo: '
+add_conf "'%\$!foo%'"
+add_conf '\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse")
+set $.garply = "";
+
+foreach ($.quux in $!foo) do {
+ if ($.quux!key == "str2") then {
+ set $.quux!random_key = $.quux!key;
+ unset $!foo; #because it is deep copied, the foreach loop will continue to work, but the action to print "post_suicide_foo" will not see $!foo
+ }
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="quux")
+ foreach ($.corge in $.quux!value) do {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.async.log" template="corge" queue.type="linkedlist" action.copyMsg="on")
+ }
+}
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="post_suicide_foo")
+'
+startup_vg
+tcpflood -m 1 -I $srcdir/testsuites/json_object_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+content_check 'quux: { "key": "str1", "value": "abc0" }'
+content_check 'quux: { "key": "str2", "value": "def1", "random_key": "str2" }'
+content_check 'quux: { "key": "str3", "value": "ghi2" }'
+assert_content_missing 'quux: { "key": "str4", "value": "jkl3" }'
+content_check 'quux: { "key": "obj", "value": { "bar": { "k1": "important_msg", "k2": "other_msg" } } }'
+custom_content_check 'corge: key: bar val: { "k1": "important_msg", "k2": "other_msg" }' $RSYSLOG_DYNNAME.out.async.log
+content_check "post_suicide_foo: ''"
+exit_test
diff --git a/tests/json_var_case.sh b/tests/json_var_case.sh
new file mode 100755
index 0000000..3cc7e1f
--- /dev/null
+++ b/tests/json_var_case.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# added 2015-11-24 by portant
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===========================================================================================
+echo \[json_var_case.sh\]: test for JSON upper and lower case variables, and leading underscores
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(variables.casesensitive="on")
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# we must make sure the template contains references to the variables
+template(name="outfmt" type="string" string="abc:%$!abc% ABC:%$!ABC% aBc:%$!aBc% _abc:%$!_abc% _ABC:%$!_ABC% _aBc:%$!_aBc%\n" option.casesensitive="on")
+template(name="outfmt-all-json" type="string" string="%$!all-json%\n")
+
+action(type="mmjsonparse")
+set $!_aBc = "7";
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+if $!_aBc != "7" then
+ action(type="omfile" file="./'"${RSYSLOG2_OUT_LOG}"'" template="outfmt-all-json")
+'
+startup
+tcpflood -m 1 -M "\"<167>Nov 6 12:34:56 172.0.0.1 test: @cee: { \\\"abc\\\": \\\"1\\\", \\\"ABC\\\": \\\"2\\\", \\\"aBc\\\": \\\"3\\\", \\\"_abc\\\": \\\"4\\\", \\\"_ABC\\\": \\\"5\\\", \\\"_aBc\\\": \\\"6\\\" }\""
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+# NOTE: conf file updates _aBc to "7"
+content_check "abc:1 ABC:2 aBc:3 _abc:4 _ABC:5 _aBc:7"
+exit_test
diff --git a/tests/json_var_cmpr.sh b/tests/json_var_cmpr.sh
new file mode 100755
index 0000000..ee21be8
--- /dev/null
+++ b/tests/json_var_cmpr.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# added 2015-11-24 by portant
+# This file is part of the rsyslog project, released under ASL 2.0
+echo =============================================================================================
+echo \[json_var_case.sh\]: test for referencing local and global variables properly in comparisons
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# we must make sure the template contains references to the variables
+template(name="outfmt" type="string" string="json prop:%$!val% local prop:%$.val% global prop:%$/val%\n")
+
+action(type="mmjsonparse")
+
+set $.val = "123";
+set $.rval = "123";
+if ($.val == $.rval) then {
+ set $.val = "def";
+}
+set $/val = "123";
+set $/rval = "123";
+if ($/val == $/rval) then {
+ set $/val = "ghi";
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1 -M "\"<167>Nov 6 12:34:56 172.0.0.1 test: @cee: { \\\"val\\\": \\\"abc\\\" }\""
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "json prop:abc local prop:def global prop:ghi"
+exit_test
diff --git a/tests/kafka-selftest.sh b/tests/kafka-selftest.sh
new file mode 100755
index 0000000..9b38fe0
--- /dev/null
+++ b/tests/kafka-selftest.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+# added 2018-10-26 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+check_command_available kafkacat
+export KEEP_KAFKA_RUNNING="YES"
+
+export TESTMESSAGES=100000
+
+export RANDTOPIC=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+
+# Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only.
+#export EXTRA_EXITCHECK=dumpkafkalogs
+export EXTRA_EXIT=kafka
+download_kafka
+stop_zookeeper
+stop_kafka
+
+start_zookeeper
+start_kafka
+create_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+printf 'injecting messages via kafkacat\n'
+injectmsg_kafkacat
+
+# experimental: wait until kafkacat receives everything
+
+timeoutend=10
+timecounter=0
+
+printf 'receiving messages via kafkacat\n'
+while [ $timecounter -lt $timeoutend ]; do
+ (( timecounter++ ))
+
+ kafkacat -b localhost:29092 -e -C -o beginning -t $RANDTOPIC -f '%s\n' > $RSYSLOG_OUT_LOG
+ count=$(wc -l < ${RSYSLOG_OUT_LOG})
+ if [ $count -eq $TESTMESSAGES ]; then
+ printf '**** wait-kafka-lines success, have %d lines ****\n\n' "$TESTMESSAGES"
+ break
+ else
+ if [ "x$timecounter" == "x$timeoutend" ]; then
+ echo wait-kafka-lines failed, expected $TESTMESSAGES got $count
+ error_exit 1
+ else
+ echo wait-file-lines not yet there, currently $count lines
+ printf '\n'
+ $TESTTOOL_DIR/msleep 1000
+ fi
+ fi
+done
+unset count
+
+#end experimental
+
+delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+sed -i 's/ msgnum://' "$RSYSLOG_OUT_LOG"
+seq_check 1 $TESTMESSAGES -d
+
+exit_test
diff --git a/tests/key_dereference_on_uninitialized_variable_space.sh b/tests/key_dereference_on_uninitialized_variable_space.sh
new file mode 100755
index 0000000..d9c6f4e
--- /dev/null
+++ b/tests/key_dereference_on_uninitialized_variable_space.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# added 2015-05-27 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[key_dereference_on_uninitialized_variable_space.sh\]: test to dereference key from a not-yet-created cee or local json-object
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="corge" type="string" string="cee:%$!%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+
+ruleset(name="echo") {
+ if ($!foo == "bar") then {
+ set $!baz = "quux";
+ }
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="corge")
+}
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+call echo
+'
+startup
+tcpflood -m 10
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check 'cee:'
+exit_test
diff --git a/tests/killrsyslog.sh b/tests/killrsyslog.sh
new file mode 100755
index 0000000..e5f2328
--- /dev/null
+++ b/tests/killrsyslog.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+#check if rsyslog instance exists and, if so, kill it
+if [ -e "rsyslog.pid" ]
+then
+ echo rsyslog.pid exists, trying to shut down rsyslogd process `cat rsyslog.pid`.
+ kill -9 `cat rsyslog.pid`
+ sleep 1
+ rm rsyslog.pid
+fi
+if [ -e "rsyslog2.pid" ]
+then
+ echo rsyslog2.pid exists, trying to shut down rsyslogd process `cat rsyslog2.pid`.
+ kill -9 `cat rsyslog2.pid`
+ sleep 1
+ rm rsyslog2.pid
+fi
diff --git a/tests/known_issues.supp b/tests/known_issues.supp
new file mode 100644
index 0000000..9bb8fa3
--- /dev/null
+++ b/tests/known_issues.supp
@@ -0,0 +1,62 @@
+{
+ <dlcose-missing-to-enable-debug-symbol-display_NOT_A_LEAK>
+ Memcheck:Leak
+ ...
+ fun:dlopen*
+ ...
+}
+
+{
+ <CentOS 6 GnuTLS memleak - well some older GnuTLS version actually>
+ Memcheck:Leak
+ fun:malloc
+ fun:CRYPTO_malloc
+ fun:EC_KEY_new
+ fun:EC_KEY_new_by_curve_name
+ fun:SetAuthMode
+ fun:LstnInit
+ fun:create_tcp_socket
+ fun:tcpsrvConstructFinalize
+ fun:activate
+ fun:initAll
+ fun:main
+}
+
+{
+ <pselect() sometimes reports pointing to unadressable byte when all selectors are empty>
+ Memcheck:Param
+ pselect6(sig)
+ fun:pselect
+ fun:wait_timeout
+ fun:mainloop
+ fun:main
+}
+{
+ <librdkafka mem leak - we cannot work around it>
+ Memcheck:Leak
+ ...
+ fun:checkInstance
+ fun:activateCnf
+ fun:tellModulesActivateConfig
+ fun:activate
+ fun:initAll
+}
+{
+ <known issue under Ubuntu 20.04>
+ Helgrind:Misc
+ obj:/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so
+ fun:_dl_fini
+ fun:__run_exit_handlers
+ fun:exit
+ fun:(below main)
+}
+{
+ <known issue under Ubuntu 20.04>
+ Helgrind:Misc
+ obj:/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so
+ obj:/usr/lib/x86_64-linux-gnu/libp11-kit.so.0.3.0
+ fun:_dl_fini
+ fun:__run_exit_handlers
+ fun:exit
+ fun:(below main)
+}
diff --git a/tests/libdbi-asyn.sh b/tests/libdbi-asyn.sh
new file mode 100755
index 0000000..36b319a
--- /dev/null
+++ b/tests/libdbi-asyn.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000 # this test is veeeeery slow, value is a compromise
+generate_conf
+add_conf '
+$ModLoad ../plugins/omlibdbi/.libs/omlibdbi
+
+$ActionQueueType LinkedList
+$ActionQueueTimeoutEnqueue 15000
+
+$ActionLibdbiDriver mysql
+$ActionLibdbiHost 127.0.0.1
+$ActionLibdbiUserName rsyslog
+$ActionLibdbiPassword testbench
+$ActionLibdbiDBName '$RSYSLOG_DYNNAME'
+:msg, contains, "msgnum:" {
+ :omlibdbi:
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.syncfile")
+}
+'
+mysql_prep_for_test
+startup
+injectmsg
+wait_file_lines $RSYSLOG_DYNNAME.syncfile $NUMMESSAGES 2500
+shutdown_when_empty
+wait_shutdown
+mysql_get_data
+seq_check
+exit_test
diff --git a/tests/libdbi-basic-vg.sh b/tests/libdbi-basic-vg.sh
new file mode 100755
index 0000000..0ff4a88
--- /dev/null
+++ b/tests/libdbi-basic-vg.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+# this test is currently not included in the testbench as libdbi
+# itself seems to have a memory leak
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/libdbi-basic.sh
diff --git a/tests/libdbi-basic.sh b/tests/libdbi-basic.sh
new file mode 100755
index 0000000..d6bf1fa
--- /dev/null
+++ b/tests/libdbi-basic.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# basic test for libdbi-basic functionality via mysql
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+generate_conf
+add_conf '
+$ModLoad ../plugins/omlibdbi/.libs/omlibdbi
+$ActionLibdbiDriver mysql
+$ActionLibdbiHost 127.0.0.1
+$ActionLibdbiUserName rsyslog
+$ActionLibdbiPassword testbench
+$ActionLibdbiDBName '$RSYSLOG_DYNNAME'
+:msg, contains, "msgnum:" :omlibdbi:
+'
+mysql_prep_for_test
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+mysql_get_data
+seq_check
+exit_test
diff --git a/tests/libmaxmindb.supp b/tests/libmaxmindb.supp
new file mode 100644
index 0000000..71e056a
--- /dev/null
+++ b/tests/libmaxmindb.supp
@@ -0,0 +1,57 @@
+{
+ libmaxmindb_known_leak_(fixed_in_later_versions)
+ Memcheck:Leak
+ match-leak-kinds: definite
+ fun:malloc
+ fun:MMDB_open
+ fun:createWrkrInstance
+ fun:actionCheckAndCreateWrkrInstance
+ fun:actionPrepare
+ fun:actionProcessMessage
+ fun:processMsgMain
+ fun:doSubmitToActionQ
+ fun:execAct
+ fun:scriptExec
+ fun:processBatch
+ fun:msgConsumer
+}
+{
+ another_incarnation_of_the_same
+ Memcheck:Leak
+ match-leak-kinds: definite
+ fun:malloc
+ fun:populate_languages_metadata
+ fun:read_metadata
+ fun:MMDB_open
+ fun:createWrkrInstance
+ fun:actionCheckAndCreateWrkrInstance
+ fun:actionPrepare
+ fun:actionProcessMessage
+ fun:processMsgMain
+ fun:doSubmitToActionQ
+ fun:execAct
+ fun:scriptExec
+ fun:processBatch
+ fun:msgConsumer
+ fun:ConsumerReg
+ fun:wtiWorker
+}
+{
+ yet_another_incarnation
+ Memcheck:Leak
+ match-leak-kinds: definite
+ fun:malloc
+ fun:MMDB_open
+ fun:open_mmdb
+ fun:createWrkrInstance
+ fun:actionCheckAndCreateWrkrInstance
+ fun:actionPrepare
+ fun:actionProcessMessage
+ fun:processMsgMain
+ fun:doSubmitToActionQ
+ fun:execAct
+ fun:scriptExec
+ fun:processBatch
+ fun:msgConsumer
+ fun:ConsumerReg
+} \ No newline at end of file
diff --git a/tests/linkedlistqueue.sh b/tests/linkedlistqueue.sh
new file mode 100755
index 0000000..25d49be
--- /dev/null
+++ b/tests/linkedlistqueue.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# Test for Linkedlist queue mode
+# added 2009-05-20 by rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=40000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+# set spool locations and switch queue to disk-only mode
+$MainMsgQueueType LinkedList
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/linux_localtime_r.supp b/tests/linux_localtime_r.supp
new file mode 100644
index 0000000..1cd3e1b
--- /dev/null
+++ b/tests/linux_localtime_r.supp
@@ -0,0 +1,126 @@
+{
+ linux-localtime_r-apparently-modifies-TZ
+ Helgrind:Race
+ ...
+ fun:__tz_convert
+ fun:timeval2syslogTime
+ ...
+}
+
+{
+ linux-localtime_r-apparently-modifies-TZ
+ Helgrind:Race
+ fun:strlen
+ fun:__tzset_parse_tz
+ fun:__tzfile_compute
+ fun:__tz_convert
+ ...
+}
+
+{
+ linux-localtime_r-apparently-modifies-TZ
+ Helgrind:Race
+ ...
+ fun:__tzstring
+ fun:__tzfile_compute
+ fun:__tz_convert
+ ...
+}
+
+{
+ linux-localtime_r-apparently-modifies-TZ-2
+ Helgrind:Race
+ fun:__GI_strcmp
+ fun:__tzfile_compute
+ fun:__tz_convert
+ ...
+}
+
+{
+ CENTOS_6_only_report
+ Helgrind:Misc
+ fun:pthread_cond_destroy_WRK
+ fun:pthread_cond_destroy@*
+ fun:modExit
+ fun:modUnlinkAndDestroy
+ fun:Release
+ fun:ReleaseObj
+ fun:modExit
+ ...
+}
+{
+ CENTOS_6_only_report
+ Helgrind:Misc
+ fun:pthread_cond_destroy_WRK
+ fun:pthread_cond_destroy@*
+ fun:qqueueDestruct
+ fun:actionDestruct
+ fun:cnfstmtDestruct
+ fun:cnfstmtDestructLst
+ fun:cnfstmtDestruct
+ fun:cnfstmtDestructLst
+ fun:rulesetDestruct
+ fun:rulesetDestructForLinkedList
+ fun:llDestroyElt
+ fun:llDestroy
+}
+{
+ CENTOS_6_only_report
+ Helgrind:Misc
+ fun:pthread_cond_destroy_WRK
+ fun:pthread_cond_destroy@*
+ fun:modExit
+ fun:modUnlinkAndDestroy
+ fun:modUnloadAndDestructAll
+ fun:main
+}
+{
+ CENTOS_7_github_rsyslog_issue_2012
+ Helgrind:Race
+ fun:GetLocalHostIP
+ fun:logmsgInternalSubmit
+ fun:logmsgInternal
+ fun:doLogMsg.constprop.0
+ fun:LogMsg
+ fun:wtpAdviseMaxWorkers
+ fun:qqueueAdviseMaxWorkers
+ fun:qqueueMultiEnqObjNonDirect
+ fun:multiSubmitMsg2
+ fun:ratelimitAddMsg
+ fun:enqLine
+ fun:pollFileReal
+ fun:pollFile
+ fun:doPolling
+ fun:runInput
+ fun:thrdStarter
+}
+{
+ CENTOS_7_github_rsyslog_issue_2012
+ Helgrind:Race
+ fun:AddRef
+ fun:MsgSetRcvFromIP
+ fun:logmsgInternalSubmit
+ fun:logmsgInternal
+ fun:doLogMsg.constprop.0
+ fun:LogMsg
+ fun:wtpAdviseMaxWorkers
+ fun:qqueueAdviseMaxWorkers
+ fun:qqueueMultiEnqObjNonDirect
+ fun:multiSubmitMsg2
+ fun:ratelimitAddMsg
+ fun:enqLine
+ fun:pollFileReal
+ fun:pollFile
+ fun:doPolling
+ fun:runInput
+}
+{
+ CENTOS_7_github_rsyslog_issue_2012
+ Helgrind:Race
+ fun:thrdDestruct
+ fun:llDestroyElt
+ fun:llDestroy
+ fun:thrdTerminateAll
+ fun:deinitAll
+ fun:main
+}
diff --git a/tests/loadbalance.sh b/tests/loadbalance.sh
new file mode 100755
index 0000000..06a2a47
--- /dev/null
+++ b/tests/loadbalance.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# a test to check load balancing via global variables
+# note: for simplicity, we use omfile output; in practice this will usually
+# be some kind of network output, e.g. omfwd or omrelp. From the method's
+# point of view, the actual output does not matter.
+# added by Rainer Gerhards 2020-01-03
+# part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000 # sufficient for our needs
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+# note: do NOT initialize $/lbcntr - it starts at "", which becomes 0 after cnum()
+if $msg contains "msgnum" then {
+ set $.actnbr = cnum($/lbcntr) % 4;
+ if $.actnbr == 0 then {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'0.log" template="outfmt")
+ } else if $.actnbr == 1 then {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'1.log" template="outfmt")
+ } else if $.actnbr == 2 then {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'2.log" template="outfmt")
+ } else {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'3.log" template="outfmt")
+ }
+ set $/lbcntr = cnum($/lbcntr) + 1;
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check # validate test result as such
+export SEQ_CHECK_FILE="${RSYSLOG_DYNNAME}0.log"
+seq_check 0 $((NUMMESSAGES -4)) -i 4
+printf 'Checking file 1\n'
+export SEQ_CHECK_FILE="${RSYSLOG_DYNNAME}1.log"
+printf 'Checking file 2\n'
+export SEQ_CHECK_FILE="${RSYSLOG_DYNNAME}2.log"
+printf 'Checking file 3\n'
+export SEQ_CHECK_FILE="${RSYSLOG_DYNNAME}3.log"
+exit_test
diff --git a/tests/localvar-concurrency.sh b/tests/localvar-concurrency.sh
new file mode 100755
index 0000000..6d564f0
--- /dev/null
+++ b/tests/localvar-concurrency.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# Test concurrency of message variables
+# Added 2015-11-03 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[localvar-concurrency.sh\]: testing concurrency of local variables
+
+uname
+if [ $(uname) = "SunOS" ] ; then
+ echo "This test currently does not work on all flavors of Solaris."
+ exit 77
+fi
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%$.tree!here!nbr%\n")
+
+if $msg contains "msgnum:" then {
+ set $.tree!here!nbr = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt"
+ queue.type="linkedList")
+
+ set $.tree!here!save = $.tree!here!nbr;
+ set $.tree!here!nbr = "";
+ set $.tree!here!nbr = $.tree!here!save;
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+sleep 1
+tcpflood -m500000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 499999
+exit_test
diff --git a/tests/lookup_table-hup-backgrounded.sh b/tests/lookup_table-hup-backgrounded.sh
new file mode 100755
index 0000000..bc43c45
--- /dev/null
+++ b/tests/lookup_table-hup-backgrounded.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# test for lookup-table and HUP based reloading of it
+# added 2015-09-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_TSAN
+generate_conf
+add_conf '
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl" reloadOnHUP="on")
+
+template(name="outfmt" type="string" string="- %msg% %$.lkp%\n")
+
+set $.lkp = lookup("xlate", $msg);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+export RSTB_DAEMONIZE="YES"
+startup
+injectmsg 0 3
+wait_queueempty
+content_check "msgnum:00000000: foo_old"
+content_check "msgnum:00000001: bar_old"
+assert_content_missing "baz"
+cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 3
+wait_queueempty
+content_check "msgnum:00000000: foo_new"
+content_check "msgnum:00000001: bar_new"
+content_check "msgnum:00000002: baz"
+cp -f $srcdir/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 10
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "msgnum:00000000: foo_latest"
+content_check "msgnum:00000001: quux"
+content_check "msgnum:00000002: baz_latest"
+content_check "msgnum:00000003: foo_latest"
+content_check "msgnum:00000004: foo_latest"
+content_check "msgnum:00000005: baz_latest"
+content_check "msgnum:00000006: foo_latest"
+content_check "msgnum:00000007: baz_latest"
+content_check "msgnum:00000008: baz_latest"
+content_check "msgnum:00000009: quux"
+exit_test
diff --git a/tests/lookup_table-vg.sh b/tests/lookup_table-vg.sh
new file mode 100755
index 0000000..2aad430
--- /dev/null
+++ b/tests/lookup_table-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# added 2015-09-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/lookup_table.sh
diff --git a/tests/lookup_table.sh b/tests/lookup_table.sh
new file mode 100755
index 0000000..fe47903
--- /dev/null
+++ b/tests/lookup_table.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# test for lookup-table and HUP based reloading of it
+# added 2015-09-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl" reloadOnHUP="on")
+
+template(name="outfmt" type="string" string="- %msg% %$.lkp%\n")
+
+set $.lkp = lookup("xlate", $msg);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+startup
+injectmsg 0 3
+wait_queueempty
+content_check "msgnum:00000000: foo_old"
+content_check "msgnum:00000001: bar_old"
+assert_content_missing "baz"
+cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 3
+wait_queueempty
+content_check "msgnum:00000000: foo_new"
+content_check "msgnum:00000001: bar_new"
+content_check "msgnum:00000002: baz"
+cp -f $srcdir/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 10
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "msgnum:00000000: foo_latest"
+content_check "msgnum:00000001: quux"
+content_check "msgnum:00000002: baz_latest"
+content_check "msgnum:00000003: foo_latest"
+content_check "msgnum:00000004: foo_latest"
+content_check "msgnum:00000005: baz_latest"
+content_check "msgnum:00000006: foo_latest"
+content_check "msgnum:00000007: baz_latest"
+content_check "msgnum:00000008: baz_latest"
+content_check "msgnum:00000009: quux"
+exit_test
diff --git a/tests/lookup_table_bad_configs-vg.sh b/tests/lookup_table_bad_configs-vg.sh
new file mode 100755
index 0000000..e6d3b25
--- /dev/null
+++ b/tests/lookup_table_bad_configs-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# added 2015-12-02 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/lookup_table_bad_configs.sh
diff --git a/tests/lookup_table_bad_configs.sh b/tests/lookup_table_bad_configs.sh
new file mode 100755
index 0000000..7d20c9c
--- /dev/null
+++ b/tests/lookup_table_bad_configs.sh
@@ -0,0 +1,160 @@
+#!/bin/bash
+# added 2015-12-02 by singh.janmejay
+# test for sparse-array lookup-table and HUP based reloading of it
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl")
+
+template(name="outfmt" type="string" string="%msg% %$.lkp%\n")
+
+set $.num = field($msg, 58, 2);
+set $.lkp = lookup("xlate", $.num);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+
+echo "empty file..."
+cp -f $srcdir/testsuites/xlate_empty_file.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+startup
+injectmsg 0 5
+wait_queueempty
+
+echo "table with invalid-json..."
+cp -f $srcdir/testsuites/xlate_invalid_json.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+
+echo "string-table with no index-key..."
+cp -f $srcdir/testsuites/xlate_string_no_index.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+assert_content_missing "foo"
+assert_content_missing "bar"
+assert_content_missing "baz"
+
+echo "array-table with no index-key..."
+cp -f $srcdir/testsuites/xlate_array_no_index.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+assert_content_missing "foo"
+assert_content_missing "bar"
+assert_content_missing "baz"
+
+echo "sparse-array-table with no index-key..."
+cp -f $srcdir/testsuites/xlate_sparseArray_no_index.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+assert_content_missing "foo"
+assert_content_missing "bar"
+assert_content_missing "baz"
+
+echo "string-table with no value..."
+cp -f $srcdir/testsuites/xlate_string_no_value.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+assert_content_missing "baz"
+
+echo "array-table with no value..."
+cp -f $srcdir/testsuites/xlate_array_no_value.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+assert_content_missing "baz"
+
+echo "sparse-array-table with no value..."
+cp -f $srcdir/testsuites/xlate_sparseArray_no_value.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+assert_content_missing "baz"
+
+echo "incorrect-version in lookup-table..."
+cp -f $srcdir/testsuites/xlate_incorrect_version.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+assert_content_missing "foo"
+assert_content_missing "bar"
+assert_content_missing "baz"
+
+echo "incorrect-type in lookup-table..."
+cp -f $srcdir/testsuites/xlate_incorrect_type.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+assert_content_missing "foo"
+assert_content_missing "bar"
+assert_content_missing "baz"
+
+echo "string-table with no table..."
+cp -f $srcdir/testsuites/xlate_string_no_table.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+assert_content_missing "baz"
+
+echo "array-table with no table..."
+cp -f $srcdir/testsuites/xlate_array_no_table.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+assert_content_missing "baz"
+
+echo "sparse-array-table with no table..."
+cp -f $srcdir/testsuites/xlate_sparseArray_no_table.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 5
+wait_queueempty
+assert_content_missing "baz"
+
+echo "string-table with empty table..."
+cp -f $srcdir/testsuites/xlate_string_empty_table.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 2
+wait_queueempty
+content_check "msgnum:00000000: baz_str"
+content_check "msgnum:00000001: baz_str"
+
+echo "array-table with empty table..."
+cp -f $srcdir/testsuites/xlate_array_empty_table.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 2
+wait_queueempty
+content_check "msgnum:00000000: baz_arr"
+content_check "msgnum:00000001: baz_arr"
+
+echo "sparse-array-table with empty table..."
+cp -f $srcdir/testsuites/xlate_sparseArray_empty_table.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 2
+wait_queueempty
+content_check "msgnum:00000000: baz_sparse_arr"
+content_check "msgnum:00000001: baz_sparse_arr"
+
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+exit_test
diff --git a/tests/lookup_table_no_hup_reload-vg.sh b/tests/lookup_table_no_hup_reload-vg.sh
new file mode 100755
index 0000000..e895828
--- /dev/null
+++ b/tests/lookup_table_no_hup_reload-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# added 2015-09-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/lookup_table_no_hup_reload.sh
diff --git a/tests/lookup_table_no_hup_reload.sh b/tests/lookup_table_no_hup_reload.sh
new file mode 100755
index 0000000..4dc1963
--- /dev/null
+++ b/tests/lookup_table_no_hup_reload.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# test for lookup-table with HUP based reloading disabled
+# added 2015-09-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl" reloadOnHUP="off")
+
+template(name="outfmt" type="string" string="- %msg% %$.lkp%\n")
+
+set $.lkp = lookup("xlate", $msg);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+startup
+injectmsg 0 3
+wait_queueempty
+content_check "msgnum:00000000: foo_old"
+content_check "msgnum:00000001: bar_old"
+assert_content_missing "baz"
+cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 3
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+assert_content_missing "foo_new"
+assert_content_missing "bar_new"
+assert_content_missing "baz"
+exit_test
diff --git a/tests/lookup_table_rscript_reload-vg.sh b/tests/lookup_table_rscript_reload-vg.sh
new file mode 100755
index 0000000..7fd0532
--- /dev/null
+++ b/tests/lookup_table_rscript_reload-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# added 2015-12-18 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/lookup_table_rscript_reload.sh
diff --git a/tests/lookup_table_rscript_reload.sh b/tests/lookup_table_rscript_reload.sh
new file mode 100755
index 0000000..fbc6417
--- /dev/null
+++ b/tests/lookup_table_rscript_reload.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# test for lookup-table reload by rscript-fn
+# added 2015-12-18 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test currently does not work on FreeBSD"
+generate_conf
+add_conf '
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl")
+
+template(name="outfmt" type="string" string="- %msg% %$.lkp%\n")
+
+set $.lkp = lookup("xlate", $msg);
+
+if ($msg == " msgnum:00000002:") then {
+ reload_lookup_table("xlate", "reload_failed");
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+startup
+# the last message ..002 should cause successful lookup-table reload
+cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+injectmsg 0 3
+await_lookup_table_reload
+wait_queueempty
+content_check "msgnum:00000000: foo_old"
+content_check "msgnum:00000001: bar_old"
+assert_content_missing "baz"
+cp -f $srcdir/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+injectmsg 0 3
+await_lookup_table_reload
+wait_queueempty
+content_check "msgnum:00000000: foo_new"
+content_check "msgnum:00000001: bar_new"
+content_check "msgnum:00000002: baz"
+rm -f $RSYSLOG_DYNNAME.xlate.lkp_tbl # this should lead to unsuccessful reload
+injectmsg 0 3
+await_lookup_table_reload
+wait_queueempty
+injectmsg 0 2
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "msgnum:00000000: foo_latest"
+content_check "msgnum:00000001: quux"
+content_check "msgnum:00000002: baz_latest"
+content_check "msgnum:00000000: reload_failed"
+content_check "msgnum:00000000: reload_failed"
+
+exit_test
diff --git a/tests/lookup_table_rscript_reload_without_stub-vg.sh b/tests/lookup_table_rscript_reload_without_stub-vg.sh
new file mode 100755
index 0000000..8a65d28
--- /dev/null
+++ b/tests/lookup_table_rscript_reload_without_stub-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# added 2015-12-18 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/lookup_table_rscript_reload_without_stub.sh
diff --git a/tests/lookup_table_rscript_reload_without_stub.sh b/tests/lookup_table_rscript_reload_without_stub.sh
new file mode 100755
index 0000000..209873d
--- /dev/null
+++ b/tests/lookup_table_rscript_reload_without_stub.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# test for lookup-table reload by rscript-stmt without stub
+# added 2015-12-18 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test currently does not work on FreeBSD"
+generate_conf
+add_conf '
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl")
+
+template(name="outfmt" type="string" string="- %msg% %$.lkp%\n")
+
+set $.lkp = lookup("xlate", $msg);
+
+if ($msg == " msgnum:00000002:") then {
+ reload_lookup_table("xlate")
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+startup
+# the last message ..002 should cause successful lookup-table reload
+cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+injectmsg 0 3
+await_lookup_table_reload
+wait_queueempty
+content_check "msgnum:00000000: foo_old"
+content_check "msgnum:00000001: bar_old"
+assert_content_missing "baz"
+cp -f $srcdir/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+injectmsg 0 3
+await_lookup_table_reload
+wait_queueempty
+content_check "msgnum:00000000: foo_new"
+content_check "msgnum:00000001: bar_new"
+content_check "msgnum:00000002: baz"
+rm -f $RSYSLOG_DYNNAME.xlate.lkp_tbl # this should lead to unsuccessful reload
+injectmsg 0 3
+await_lookup_table_reload
+wait_queueempty
+injectmsg 0 2
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check_with_count "msgnum:00000000: foo_latest" 2
+content_check_with_count "msgnum:00000001: quux" 2
+content_check_with_count "msgnum:00000002: baz_latest" 1
+
+exit_test
diff --git a/tests/mainq_actq_DA.sh b/tests/mainq_actq_DA.sh
new file mode 100755
index 0000000..88f4a72
--- /dev/null
+++ b/tests/mainq_actq_DA.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Test to check that mainq and actionq can be disk assisted without
+# any problems. This was created to reproduce a segfault issue:
+# https://github.com/rsyslog/rsyslog/issues/3681
+# added 2019-06-03 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10 # we just need a handful - we primarily test startup
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+main_queue(queue.fileName="main" queue.type="LinkedList")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:"
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt"
+ queue.type="linkedList" queue.fileName="action")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/mangle_qi.c b/tests/mangle_qi.c
new file mode 100644
index 0000000..3775c96
--- /dev/null
+++ b/tests/mangle_qi.c
@@ -0,0 +1,113 @@
+/* rsyslog testbench tool to mangle .qi files
+ *
+ * Copyright (C) 2016 by Rainer Gerhards
+ * Released uner ASL 2.0
+ */
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+
+static int debug = 0;
+
+void
+usage(void)
+{
+ fprintf(stderr, "mangle_qi -d -q <.qi-file>\n"
+ "-d enables debug messages\n");
+ exit(1);
+}
+
+void
+processQI(FILE *const __restrict__ qi)
+{
+ char lnbuf[4096];
+ char propname[64];
+ int rectype;
+ int length;
+ int queuesize;
+ int i;
+ int c;
+ fgets(lnbuf, sizeof(lnbuf), qi);
+ fputs(lnbuf, stdout);
+ /* we now read the queue size line */
+ /* note: this is quick and dirty, no error checks
+ * are done!
+ */
+ fgetc(qi); /* skip '+' */
+ for(i = 0 ; (c = fgetc(qi)) != ':' ; ++i) {
+ propname[i] = c;
+ }
+ propname[i] = '\0';
+ if(strcmp(propname, "iQueueSize")) {
+ fprintf(stderr, ".qi file format unknown: line 2 does "
+ "not contain iQueueSize property, instead '%s'\n",
+ propname);
+ exit(1);
+ }
+
+ rectype = 0;
+ for(c = fgetc(qi) ; isdigit(c) ; c = fgetc(qi))
+ rectype = rectype * 10 + c - '0';
+
+ length = 0;
+ for(c = fgetc(qi) ; isdigit(c) ; c = fgetc(qi))
+ length = length * 10 + c - '0';
+
+ queuesize = 0;
+ for(c = fgetc(qi) ; isdigit(c) ; c = fgetc(qi))
+ queuesize = queuesize * 10 + c - '0';
+
+ int maxval_for_length = 10;
+ for(i = 1 ; i < length ; ++i)
+ maxval_for_length *= 10; /* simulate int-exp() */
+
+ if(debug) {
+ fprintf(stderr, "rectype: %d\n", rectype);
+ fprintf(stderr, "length: %d\n", length);
+ fprintf(stderr, "queuesize: %d\n", queuesize);
+ fprintf(stderr, "maxval_for_length: %d\n", maxval_for_length);
+ }
+
+ queuesize += 1; /* fake invalid queue size */
+ if(queuesize > maxval_for_length)
+ ++length;
+
+ /* ready to go, write mangled queue size */
+ printf("+%s:%d:%d:%d:", propname, rectype, length, queuesize);
+ /* copy rest of file */
+ while((c = fgetc(qi)) != EOF)
+ putchar(c);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *qifile = NULL;
+ FILE *qi;
+ int opt;
+ while((opt = getopt(argc, argv, "dq:")) != -1) {
+ switch (opt) {
+ case 'q': qifile = optarg;
+ break;
+ case 'd': debug = 1;
+ break;
+ default: usage();
+ break;
+ }
+ }
+
+ if(qifile == NULL) {
+ fprintf(stderr, "ERROR: -q option MUST be specified\n");
+ usage();
+ }
+
+ if((qi = fopen(qifile, "r")) == NULL) {
+ perror(qifile);
+ exit(1);
+ }
+ processQI(qi);
+ return 0;
+}
diff --git a/tests/mangle_qi_usage_output.sh b/tests/mangle_qi_usage_output.sh
new file mode 100755
index 0000000..4da5912
--- /dev/null
+++ b/tests/mangle_qi_usage_output.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+# add 2018-11-13 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+
+./mangle_qi &> $RSYSLOG_DYNNAME.output
+grep -q -- "-q option MUST be specified" $RSYSLOG_DYNNAME.output
+
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated"
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/manyptcp.sh b/tests/manyptcp.sh
new file mode 100755
index 0000000..6734f86
--- /dev/null
+++ b/tests/manyptcp.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# test imptcp with large connection count
+# test many concurrent tcp connections
+# released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=40000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+$MaxOpenFiles 2000
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+tcpflood -c1000 -m$NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/manytcp-too-few-tls-vg.sh b/tests/manytcp-too-few-tls-vg.sh
new file mode 100755
index 0000000..b03fdb9
--- /dev/null
+++ b/tests/manytcp-too-few-tls-vg.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test does not work on FreeBSD"
+export NUMMESSAGES=40000 # we unfortunately need many messages as we have many connections
+export TB_TEST_MAX_RUNTIME=1800 # this test is VERY slow, so we need to override max runtime
+generate_conf
+add_conf '
+$MaxOpenFiles 200
+global(
+ defaultNetstreamDriverCAFile="'$srcdir'/testsuites/x.509/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/testsuites/x.509/client-cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/testsuites/x.509/client-key.pem"
+ defaultNetstreamDriver="gtls"
+ debug.whitelist="on"
+ debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module(load="../plugins/imtcp/.libs/imtcp" maxSessions="1100"
+ streamDriver.mode="1" streamDriver.authMode="anon")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup_vg
+# the config file specifies exactly 1100 connections
+tcpflood -c1000 -m$NUMMESSAGES -Ttls -x$srcdir/testsuites/x.509/ca.pem -Z$srcdir/testsuites/x.509/client-cert.pem -z$srcdir/testsuites/x.509/client-key.pem
+# the sleep below is needed to prevent too-early termination of the tcp listener
+# note: this must not be precise, as message loss is acceptable
+sleep 5
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+# we do not do a seq check, as of the design of this test some messages
+# will be lost. So there is no point in checking if all were received. The
+# point is that we look at the valgrind result, to make sure we do not
+# have a mem leak in those error cases (we had in the past, thus the test
+# to prevent that in the future).
+exit_test
diff --git a/tests/manytcp.sh b/tests/manytcp.sh
new file mode 100755
index 0000000..07c0e22
--- /dev/null
+++ b/tests/manytcp.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# test many concurrent tcp connections
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test currently does not work on FreeBSD"
+skip_platform "SunOS" "timing on connection establishment is different on solaris and makes this test fail"
+export NUMMESSAGES=40000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+$MaxOpenFiles 2100
+module(load="../plugins/imtcp/.libs/imtcp" maxSessions="2100")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+# we first send a single message so that the output file is opened. Otherwise, we may
+# use up all file handles for tcp connections and so the output file could eventually
+# not be opened. 2019-03-18 rgerhards
+tcpflood -m1
+tcpflood -c-2000 -i1 -m $((NUMMESSAGES - 1 ))
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/miniamqpsrvr.c b/tests/miniamqpsrvr.c
new file mode 100644
index 0000000..5aedacd
--- /dev/null
+++ b/tests/miniamqpsrvr.c
@@ -0,0 +1,658 @@
+/* a very simplistic tcp receiver for the rsyslog testbench.
+ *
+ * Author Philippe Duveau
+ *
+ * This file is contribution of the rsyslog project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * -or-
+ * see COPYING.ASL20 in the source distribution
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <signal.h>
+#include <errno.h>
+#if defined(__FreeBSD__)
+#include <netinet/in.h>
+#endif
+
+#include "rsyslog.h"
+
+
+#include <amqp.h>
+#include <amqp_framing.h>
+
+#define AMQP_STARTING ((uchar)0x10)
+#define AMQP_STOP ((uchar)0x00)
+
+#define AMQP_BEHAVIOR_STANDARD 1
+#define AMQP_BEHAVIOR_NOEXCH 2
+#define AMQP_BEHAVIOR_DECEXCH 3
+#define AMQP_BEHAVIOR_BADEXCH 4
+
+uchar connection_start[487] = {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDF, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x00, 0x01,
+ 0xBA, 0x0C, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6C, 0x69, 0x74, 0x69, 0x65, 0x73, 0x46, 0x00,
+ 0x00, 0x00, 0xC7, 0x12, 0x70, 0x75, 0x62, 0x6C, 0x69, 0x73, 0x68, 0x65, 0x72, 0x5F, 0x63, 0x6F,
+ 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x73, 0x74, 0x01, 0x1A, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6E, 0x67,
+ 0x65, 0x5F, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6E, 0x67, 0x65, 0x5F, 0x62, 0x69, 0x6E, 0x64, 0x69,
+ 0x6E, 0x67, 0x73, 0x74, 0x01, 0x0A, 0x62, 0x61, 0x73, 0x69, 0x63, 0x2E, 0x6E, 0x61, 0x63, 0x6B,
+ 0x74, 0x01, 0x16, 0x63, 0x6F, 0x6E, 0x73, 0x75, 0x6D, 0x65, 0x72, 0x5F, 0x63, 0x61, 0x6E, 0x63,
+ 0x65, 0x6C, 0x5F, 0x6E, 0x6F, 0x74, 0x69, 0x66, 0x79, 0x74, 0x01, 0x12, 0x63, 0x6F, 0x6E, 0x6E,
+ 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x2E, 0x62, 0x6C, 0x6F, 0x63, 0x6B, 0x65, 0x64, 0x74, 0x01,
+ 0x13, 0x63, 0x6F, 0x6E, 0x73, 0x75, 0x6D, 0x65, 0x72, 0x5F, 0x70, 0x72, 0x69, 0x6F, 0x72, 0x69,
+ 0x74, 0x69, 0x65, 0x73, 0x74, 0x01, 0x1C, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x74, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x5F, 0x66, 0x61, 0x69, 0x6C, 0x75, 0x72, 0x65, 0x5F, 0x63, 0x6C,
+ 0x6F, 0x73, 0x65, 0x74, 0x01, 0x10, 0x70, 0x65, 0x72, 0x5F, 0x63, 0x6F, 0x6E, 0x73, 0x75, 0x6D,
+ 0x65, 0x72, 0x5F, 0x71, 0x6F, 0x73, 0x74, 0x01, 0x0F, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x5F,
+ 0x72, 0x65, 0x70, 0x6C, 0x79, 0x5F, 0x74, 0x6F, 0x74, 0x01, 0x0C, 0x63, 0x6C, 0x75, 0x73, 0x74,
+ 0x65, 0x72, 0x5F, 0x6E, 0x61, 0x6D, 0x65, 0x53, 0x00, 0x00, 0x00, 0x0D, 0x72, 0x61, 0x62, 0x62,
+ 0x69, 0x74, 0x40, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x09, 0x63, 0x6F, 0x70, 0x79, 0x72, 0x69,
+ 0x67, 0x68, 0x74, 0x53, 0x00, 0x00, 0x00, 0x2E, 0x43, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68,
+ 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x30, 0x37, 0x2D, 0x32, 0x30, 0x31, 0x36, 0x20,
+ 0x50, 0x69, 0x76, 0x6F, 0x74, 0x61, 0x6C, 0x20, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
+ 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x0B, 0x69, 0x6E, 0x66, 0x6F, 0x72, 0x6D, 0x61, 0x74, 0x69,
+ 0x6F, 0x6E, 0x53, 0x00, 0x00, 0x00, 0x35, 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x64, 0x20,
+ 0x75, 0x6E, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4D, 0x50, 0x4C, 0x2E, 0x20, 0x20,
+ 0x53, 0x65, 0x65, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x72,
+ 0x61, 0x62, 0x62, 0x69, 0x74, 0x6D, 0x71, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x08, 0x70, 0x6C, 0x61,
+ 0x74, 0x66, 0x6F, 0x72, 0x6D, 0x53, 0x00, 0x00, 0x00, 0x0A, 0x45, 0x72, 0x6C, 0x61, 0x6E, 0x67,
+ 0x2F, 0x4F, 0x54, 0x50, 0x07, 0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x74, 0x53, 0x00, 0x00, 0x00,
+ 0x08, 0x52, 0x61, 0x62, 0x62, 0x69, 0x74, 0x4D, 0x51, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F,
+ 0x6E, 0x53, 0x00, 0x00, 0x00, 0x05, 0x33, 0x2E, 0x36, 0x2E, 0x32, 0x00, 0x00, 0x00, 0x0E, 0x41,
+ 0x4D, 0x51, 0x50, 0x4C, 0x41, 0x49, 0x4E, 0x20, 0x50, 0x4C, 0x41, 0x49, 0x4E, 0x00, 0x00, 0x00,
+ 0x05, 0x65, 0x6E, 0x5F, 0x55, 0x53, 0xCE
+};
+
+static uchar connection_tune[20] = {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x3C, 0xCE
+};
+
+static uchar connection_open_ok[13] = {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x29, 0x00, 0xCE
+};
+
+static uchar channel_open_ok[16] = {
+ 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0xCE
+};
+
+static uchar exchange_declare_ok[12] = {
+ 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x28, 0x00, 0x0B, 0xCE
+};
+
+static uchar channel_close_ok[12] = {
+ 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x14, 0x00, 0x29, 0xCE
+};
+
+static uchar connection_close_ok[12] = {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x33, 0xCE
+};
+
+static uchar channel_close_ok_on_badexch[148] = {
+ 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8C, 0x00, 0x14, 0x00, 0x28, 0x01,
+ 0x96, 0x81, 0x50, 0x52, 0x45, 0x43, 0x4F, 0x4E, 0x44, 0x49, 0x54, 0x49,
+ 0x4F, 0x4E, 0x5F, 0x46, 0x41, 0x49, 0x4C, 0x45, 0x44, 0x20, 0x2D, 0x20,
+ 0x69, 0x6E, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6C, 0x65, 0x6E, 0x74,
+ 0x20, 0x61, 0x72, 0x67, 0x20, 0x27, 0x64, 0x75, 0x72, 0x61, 0x62, 0x6C,
+ 0x65, 0x27, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x65, 0x78, 0x63, 0x68, 0x61,
+ 0x6E, 0x67, 0x65, 0x20, 0x27, 0x69, 0x6E, 0x27, 0x20, 0x69, 0x6E, 0x20,
+ 0x76, 0x68, 0x6F, 0x73, 0x74, 0x20, 0x27, 0x2F, 0x6D, 0x65, 0x74, 0x72,
+ 0x6F, 0x6C, 0x6F, 0x67, 0x69, 0x65, 0x27, 0x3A, 0x20, 0x72, 0x65, 0x63,
+ 0x65, 0x69, 0x76, 0x65, 0x64, 0x20, 0x27, 0x66, 0x61, 0x6C, 0x73, 0x65,
+ 0x27, 0x20, 0x62, 0x75, 0x74, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E,
+ 0x74, 0x20, 0x69, 0x73, 0x20, 0x27, 0x74, 0x72, 0x75, 0x65, 0x27, 0x00,
+ 0x28, 0x00, 0x0A, 0xCE
+};
+
+typedef struct {
+ uchar type;
+ ushort ch;
+ uint32_t method;
+ uint16_t header_flags;
+ size_t datalen;
+ size_t framelen;
+ uchar *data;
+} amqp_frame_type_t;
+
+#define DBGPRINTF0(f, ...) if (debug>0) { \
+ struct timeval dbgtv; \
+ gettimeofday(&dbgtv, NULL);\
+ fprintf(stderr, "%02d.%03d " f, (int)(dbgtv.tv_sec % 60), \
+ (int)(dbgtv.tv_usec/1000), __VA_ARGS__); \
+}
+#define DBGPRINTF1(f, ...) if (debug>0) { \
+ struct timeval dbgtv; \
+ gettimeofday(&dbgtv, NULL);\
+ dbgtv.tv_sec -= dbgtv_base.tv_sec; \
+ dbgtv.tv_usec -= dbgtv_base.tv_usec; \
+ if (dbgtv.tv_usec < 0) { \
+ dbgtv.tv_usec += 1000000; \
+ dbgtv.tv_sec--; \
+ } \
+ fprintf(stderr, "%02d.%03d " f, (int)(dbgtv.tv_sec % 60), \
+ (int)(dbgtv.tv_usec/1000), __VA_ARGS__); \
+}
+#define DBGPRINTF2(f, ...) if (debug==2) { \
+ struct timeval dbgtv; \
+ gettimeofday(&dbgtv, NULL);\
+ dbgtv.tv_sec -= dbgtv_base.tv_sec; \
+ dbgtv.tv_usec -= dbgtv_base.tv_usec; \
+ if (dbgtv.tv_usec < 0) { \
+ dbgtv.tv_usec += 1000000; \
+ dbgtv.tv_sec--; \
+ } \
+ fprintf(stderr, "%02d.%03d " f, (int)(dbgtv.tv_sec % 60), \
+ (int)(dbgtv.tv_usec/1000), __VA_ARGS__); \
+}
+
+static struct timeval dbgtv_base;
+static int server_behaviors = 0;
+static int behaviors;
+static int wait_after_accept = 200; /* milliseconds */
+static char *outfile = NULL;
+static int debug = 1;
+
+FILE* fpout = NULL;
+
+static ATTR_NORETURN void
+errout(const char *reason, int server)
+{
+ char txt[256];
+ snprintf(txt,256,"%s server %d", reason, server);
+ perror(txt);
+ if (fpout && fpout != stdout) { fclose(fpout); fpout = NULL; }
+ if (outfile) unlink(outfile);
+ exit(1);
+}
+
+static ATTR_NORETURN void
+usage(void)
+{
+ fprintf(stderr, "usage: minirmqsrvr -f outfile [-b behaviour] "
+ "[-t keep_alive_max] [-w delay_after_fail] [-d]\n");
+ exit (1);
+}
+
+/* Those three functions are "endianess" insensitive */
+static uint16_t buf2uint16(uchar*b) {
+ return ((uint16_t)b[0]) << 8 | ((uint16_t)b[1]);
+}
+
+static uint32_t buf2uint32(uchar*b) {
+ return ((uint32_t)b[0]) << 24 | ((uint32_t)b[1]) << 16 | ((uint32_t)b[2]) << 8 | ((uint32_t)b[3]);
+}
+
+static uint64_t buf2uint64(uchar*b) {
+ return ((uint64_t)b[0]) << 56 | ((uint64_t)b[1]) << 48 | ((uint64_t)b[2]) << 40 | ((uint64_t)b[3]) << 32
+ | ((uint64_t)b[4]) << 24 | ((uint64_t)b[5]) << 16 | ((uint64_t)b[6]) << 8 | ((uint64_t)b[7]);
+}
+
+
+static char AMQP091[8] = { 'A', 'M', 'Q', 'P', 0x00, 0x00, 0x09, 0x01 };
+
+static int
+decode_frame_type(uchar *buf, amqp_frame_type_t *frame, size_t nread) {
+ if (nread == 8){
+ if (memcmp(buf, AMQP091, sizeof(AMQP091)))
+ return -1;
+ frame->framelen = 8;
+ frame->type = AMQP_STARTING;
+ frame->ch = 0;
+ return 0;
+ }
+ frame->type = buf[0];
+ frame->ch = buf2uint16(buf+1);
+ frame->datalen = buf2uint32(buf+3);
+ frame->framelen = frame->datalen + 8;
+ frame->method = buf2uint32(buf+7);
+ switch (frame->type) {
+ case AMQP_FRAME_BODY:
+ frame->data = buf + 7;
+ break;
+ default:
+ frame->data = buf + 11;
+ }
+ return 0;
+}
+
+static ssize_t
+amqp_write(int fdc, uchar *buf, size_t blen, unsigned short channel) {
+ buf[1] = (char) (channel >> 8);
+ buf[2] = (char) (channel & 0xFF);
+ return write(fdc, buf, blen);
+}
+
+static uchar *
+amqpFieldUint64(uint64_t *d, uchar *s) {
+ *d = buf2uint64(s);
+ return s + 8;
+}
+
+static uchar *
+amqpFieldUint32(uint32_t *d, uchar *s) {
+ *d = buf2uint32(s);
+ return s + 4;
+}
+
+static uchar *
+amqpFieldUint16(uint16_t *d, uchar *s) {
+ *d = buf2uint16(s);
+ return s + 2;
+}
+
+static uchar *
+amqpFieldLenFprintf(const char *pfx, uchar *s, uint32_t len) {
+ if (fpout)
+ fprintf(fpout, "%s%.*s", pfx, (int)len, (char*)s);
+ return s + len;
+}
+
+static uchar *
+amqpFieldFprintf(const char *pfx, uchar *s) {
+ uint32_t len = *s++;
+ return amqpFieldLenFprintf(pfx, s, len);
+}
+
+static uchar *
+amqpHeaderFprintf(uchar *s, uint32_t *size) {
+ uint32_t len;
+ uchar *p = amqpFieldFprintf(", ", s);
+ p++; /* value type */
+ p = amqpFieldUint32(&len, p);
+ *size -= (p - s) + len;
+ return amqpFieldLenFprintf(":", p, len);
+}
+
+static void
+amqp_srvr(int port, int srvr, int fds, int piperead, int pipewrite)
+{
+ uchar wrkBuf[8192], *p;
+ size_t nRead = 0, bsize = 0;
+ ssize_t nSent;
+ amqp_frame_type_t frame;
+ uint64_t body_ui64 = 0;
+ uint32_t props_header_size;
+ uint16_t props_flags;
+ int my_behaviour;
+ struct timeval tv;
+ fd_set rfds;
+ int nfds = ((piperead > fds)? piperead : fds) + 1;
+
+ int fdc;
+
+ my_behaviour = behaviors & 0x000F;
+ behaviors = behaviors >> 4; /* for next server */;
+
+ if(listen(fds, 0) != 0) errout("listen", port);
+
+ DBGPRINTF1("Server AMQP %d on port %d started\n", srvr, port);
+
+ tv.tv_sec = 120;
+ tv.tv_usec = 0;
+ FD_ZERO(&rfds);
+ FD_SET(fds, &rfds);
+ if (piperead > 0)
+ FD_SET(piperead, &rfds);
+
+ if (select(nfds,&rfds,NULL,NULL, &tv) == 0) {
+ exit(1);
+ }
+
+ if (piperead > 0 && FD_ISSET(piperead, &rfds)) {
+ char c;
+ int l = read(piperead, &c, 1);
+ if (l == 1) {
+ my_behaviour = behaviors & 0x000F;
+ if (my_behaviour != 0) {
+ DBGPRINTF1("Server AMQP %d on port %d switch behaviour", srvr, port);
+ } else {
+ DBGPRINTF1("Server AMQP %d on port %d leaving", srvr, port);
+ if (fpout && fpout != stdout) { fclose(fpout); fpout = NULL; }
+ exit(1);
+ }
+ }
+ }
+
+ fdc = accept(fds, NULL, NULL);
+
+ if (pipewrite > 0)
+ nSent = write(pipewrite, "N", 1);
+
+ close(fds);
+ fds = -1;
+
+ /* this let the os understand that the port is closed */
+ usleep(1000 * wait_after_accept);
+
+ frame.type = AMQP_STARTING;
+
+ while(fdc > 0) {
+ nSent = 0;
+ ssize_t rd = 0;
+ if (nRead < 12) {
+ rd = read(fdc, wrkBuf + nRead, sizeof(wrkBuf) - nRead);
+ if (rd <= 0) {
+ DBGPRINTF1("Server AMQP %d on port %d disconnected\n", srvr, port);
+ close(fdc);
+ fdc = 0;
+ break;
+ }else {
+ nRead += (size_t)rd;
+ }
+ }
+
+ if (decode_frame_type(wrkBuf, &frame, nRead)) {
+ DBGPRINTF1("Server AMQP %d on port %d killed : bad protocol\n", srvr, port);
+ close(fdc);
+ fdc = 0;
+ break;
+ }
+ if (rd > 4)
+ DBGPRINTF2("Server received : %zd\n", rd);
+
+ switch (frame.type) {
+
+ case AMQP_STARTING: /* starting handshake */
+
+ DBGPRINTF1("Server AMQP %d on port %d type %d connected\n", srvr, port, my_behaviour);
+ DBGPRINTF2("Server %d connection.start\n", srvr);
+ nSent = amqp_write(fdc, connection_start, sizeof(connection_start), frame.ch);
+ break;
+
+ case AMQP_FRAME_METHOD:
+
+ DBGPRINTF2("Server %d method : 0x%X\n", srvr, frame.method);
+
+ switch (frame.method) {
+
+ case AMQP_CONNECTION_START_OK_METHOD:
+
+ DBGPRINTF2("Server %d connection.tune\n", srvr);
+ nSent = amqp_write(fdc, connection_tune, sizeof(connection_tune), frame.ch);
+ break;
+
+ case AMQP_CONNECTION_TUNE_OK_METHOD:
+
+ DBGPRINTF2("Client %d connection.tune-ok\n", srvr);
+ nSent = 0;
+ break;
+
+ case AMQP_CONNECTION_OPEN_METHOD:
+
+ nSent = amqp_write(fdc, connection_open_ok,
+ sizeof(connection_open_ok), frame.ch);
+ DBGPRINTF2("Server %d connection.open\n", srvr);
+ break;
+
+ case AMQP_CHANNEL_OPEN_METHOD:
+
+ nSent = amqp_write(fdc, channel_open_ok,
+ sizeof(channel_open_ok), frame.ch);
+ DBGPRINTF2("Server %d channel.open\n", srvr);
+ if (my_behaviour == AMQP_BEHAVIOR_NOEXCH) {
+ close(fdc);
+ DBGPRINTF1("Server AMQP %d on port %d stopped\n", srvr, port);
+ fdc = 0;
+ frame.type = 0;
+ }
+ break;
+
+ case AMQP_EXCHANGE_DECLARE_METHOD:
+
+ if (my_behaviour == AMQP_BEHAVIOR_BADEXCH) {
+ nSent = amqp_write(fdc, channel_close_ok_on_badexch,
+ sizeof(channel_close_ok_on_badexch), frame.ch);
+ }else{
+ nSent = amqp_write(fdc, exchange_declare_ok,
+ sizeof(exchange_declare_ok), frame.ch);
+ }
+ DBGPRINTF2("Server %d exchange.declare\n", srvr);
+ if (my_behaviour == AMQP_BEHAVIOR_DECEXCH) {
+ close(fdc);
+ DBGPRINTF1("Server AMQP %d on port %d stopped\n", srvr, port);
+ fdc = 0;
+ frame.type = 0;
+ }
+ break;
+
+ case AMQP_CHANNEL_CLOSE_METHOD:
+
+ nSent = amqp_write(fdc, channel_close_ok,
+ sizeof(channel_close_ok), frame.ch);
+ DBGPRINTF2("Server %d channel.close\n", srvr);
+ break;
+
+ case AMQP_CONNECTION_CLOSE_METHOD:
+
+ nSent = amqp_write(fdc, connection_close_ok,
+ sizeof(connection_close_ok), frame.ch);
+ DBGPRINTF2("Server %d connection.close\n", srvr);
+ break;
+
+ case AMQP_BASIC_PUBLISH_METHOD:
+
+ p = amqpFieldFprintf("Exchange:", frame.data + 2);
+ amqpFieldFprintf(", routing-key:", p);
+ break;
+
+ default:
+
+ nSent = 0;
+ }
+ break;
+
+ case AMQP_FRAME_HEADER:
+
+ DBGPRINTF2("Server %d HEADERS\n", srvr);
+ p = amqpFieldUint64(&body_ui64, frame.data);
+ bsize = (size_t)body_ui64;
+ p = amqpFieldUint16(&props_flags, p);
+ if (props_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
+ p = amqpFieldFprintf(", content-type:", p);
+ }
+ if (props_flags & AMQP_BASIC_HEADERS_FLAG) {
+ p = amqpFieldUint32(&props_header_size, p);
+ while (props_header_size) {
+ p = amqpHeaderFprintf(p, &props_header_size);
+ }
+ }
+ if (props_flags & AMQP_BASIC_DELIVERY_MODE_FLAG) {
+ if (fpout)
+ fprintf(fpout, ", delivery-mode:%s", (*p++)?"transient":"persistent");
+ }
+ if (props_flags & AMQP_BASIC_EXPIRATION_FLAG) {
+ p = amqpFieldFprintf(", expiration:", p);
+ }
+ if (props_flags & AMQP_BASIC_TIMESTAMP_FLAG) {
+ if (fpout)
+ fprintf(fpout, ", timestamp:OK");
+ p += sizeof(uint64_t);
+ }
+ if (props_flags & AMQP_BASIC_APP_ID_FLAG) {
+ amqpFieldFprintf(", app-id:", p);
+ }
+ if (fpout)
+ fprintf(fpout, ", msg:");
+ break;
+
+ case AMQP_FRAME_BODY:
+
+ DBGPRINTF2("Server %d Body size left : %zu, received : %zu\n",
+ srvr, bsize, frame.datalen);
+ bsize -= frame.datalen;
+ if (fpout) {
+ fprintf(fpout, "%.*s", (int)frame.datalen, frame.data);
+ if (frame.data[frame.datalen-1] != '\n')
+ fprintf(fpout, "\n");
+ fflush(fpout);
+ }
+ break;
+
+ default:
+
+ DBGPRINTF1("Server %d unsupported frame type %d\n", srvr, frame.type);
+ close(fdc);
+ fdc = 0;
+ frame.type = 0;
+ frame.framelen = 0;
+ } /* switch (frame.type) */
+
+ nRead -= frame.framelen;
+ if (nRead>0)
+ memmove(wrkBuf, wrkBuf + frame.framelen, nRead);
+
+ if (nSent < 0) {
+ close(fdc);
+ fdc = 0;
+ }
+ } /* while(fdc) */
+ DBGPRINTF2("Leaving thread %d\n", srvr);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int port[2], fds[2], i, opt, nb_port = 1;
+ int pipeS1toS2[2] = { -1, -1 };
+ int pipeS2toS1[2] = { -1, -1 };
+ int pipeRead[2], pipeWrite[2];
+
+
+ struct sockaddr_in srvAddr[2];
+ unsigned int addrLen = sizeof(struct sockaddr_in), len;
+ pid_t pid[2];
+
+ fpout = stdout;
+
+ while((opt = getopt(argc, argv, "f:b:w:d")) != -1) {
+ switch (opt) {
+ case 'w':
+ wait_after_accept = atoi(optarg);
+ break;
+ case 'd':
+ debug = 2;
+ break;
+ case 'b':
+ server_behaviors = atoi(optarg);
+ break;
+ case 'f':
+ if(strcmp(optarg, "-")) {
+ outfile = optarg;
+ fpout = fopen(optarg, "w");
+ if(fpout == NULL){
+ fprintf(stderr, "file %s could not be created\n", outfile);
+ exit(1);
+ }
+ }
+ break;
+ default:
+ fprintf(stderr, "invalid option '%c' or value missing - terminating...\n", opt);
+ usage();
+ break;
+ }
+ }
+
+ switch (server_behaviors) {
+ case 0:
+ behaviors = AMQP_BEHAVIOR_STANDARD;
+ nb_port = 1;
+ break;
+ case 1: /* two standard servers get message successfully */
+ behaviors = AMQP_BEHAVIOR_STANDARD;
+ nb_port = 2;
+ break;
+ case 2: /* 2 servers first server which disconnect after after open channel : no declare exchange */
+ behaviors = AMQP_BEHAVIOR_NOEXCH | AMQP_BEHAVIOR_STANDARD << 4;
+ nb_port = 2;
+ break;
+ case 3: /* 2 servers first server which disconnect after declare exchange*/
+ behaviors = AMQP_BEHAVIOR_DECEXCH | AMQP_BEHAVIOR_STANDARD << 4;
+ nb_port = 2;
+ break;
+ case 4: /* one server with bad exchange declare */
+ behaviors = AMQP_BEHAVIOR_BADEXCH;
+ nb_port = 1;
+ break;
+ default:
+ fprintf(stderr,"Invalid behavior");
+ exit(1);
+ }
+
+ gettimeofday(&dbgtv_base, NULL);
+
+ port[0] = port[1] = -1;
+
+ if (nb_port == 2) {
+ if(pipe(pipeS1toS2) == -1 || pipe(pipeS2toS1) == -1) {
+ fprintf(stderr, "Pipe failed !");
+ exit(1);
+ }
+ }
+
+ pipeRead[0] = pipeS2toS1[0];
+ pipeWrite[0] = pipeS1toS2[1];
+
+ pipeRead[1] = pipeS1toS2[0];
+ pipeWrite[1] = pipeS2toS1[1];
+
+ for (i = 0; i < nb_port; i++) {
+ fds[i] = socket(AF_INET, SOCK_STREAM, 0);
+ srvAddr[i].sin_family = AF_INET;
+ srvAddr[i].sin_addr.s_addr = INADDR_ANY;
+ srvAddr[i].sin_port = 0;
+ if(bind(fds[i], (struct sockaddr *)&srvAddr[i], addrLen) != 0)
+ errout("bind", 1);
+ len = addrLen;
+ if (getsockname(fds[i], (struct sockaddr *)&srvAddr[i], &len) == -1)
+ errout("bind", i+1);
+ if ((port[i] = ntohs(srvAddr[i].sin_port)) <= 0)
+ errout("get port", i+1);
+ }
+
+ for (i = 0; i < nb_port; i++) {
+ if ((pid[i] = fork()) == -1) {
+ fprintf(stderr, "Fork failed !");
+ exit(1);
+ }
+ if (pid[i] == 0) {
+ /* this is the child */
+ if (fds[1-i] > 0) close(fds[1-i]);
+ amqp_srvr(port[i], i+1, fds[i], pipeRead[i], pipeWrite[i]);
+
+ if (fpout && fpout != stdout) fclose(fpout);
+
+ DBGPRINTF2("%s\n","Leaving server");
+ return 0;
+ }
+ }
+
+ if (nb_port==2)
+ printf("export AMQPSRVRPID1=%ld AMQPSRVRPID2=%ld PORT_AMQP1=%d PORT_AMQP2=%d",
+ (long)pid[0], (long)pid[1], port[0], port[1]);
+ else
+ printf("export AMQPSRVRPID1=%ld PORT_AMQP1=%d",
+ (long)pid[0], port[0]);
+ return 0;
+}
diff --git a/tests/minitcpsrv_usage_output.sh b/tests/minitcpsrv_usage_output.sh
new file mode 100755
index 0000000..279a608
--- /dev/null
+++ b/tests/minitcpsrv_usage_output.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+# add 2018-11-15 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+
+./minitcpsrv&> $RSYSLOG_DYNNAME.output
+grep -q -- "-t parameter missing" $RSYSLOG_DYNNAME.output
+
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated"
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/minitcpsrvr.c b/tests/minitcpsrvr.c
new file mode 100644
index 0000000..7d0f719
--- /dev/null
+++ b/tests/minitcpsrvr.c
@@ -0,0 +1,131 @@
+/* a very simplistic tcp receiver for the rsyslog testbench.
+ *
+ * Copyright 2016 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of the rsyslog project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * -or-
+ * see COPYING.ASL20 in the source distribution
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#if defined(__FreeBSD__)
+#include <netinet/in.h>
+#endif
+
+static void
+errout(char *reason)
+{
+ perror(reason);
+ exit(1);
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: minitcpsrvr -t ip-addr -p port -f outfile\n");
+ exit (1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int fds;
+ int fdc;
+ int fdf = -1;
+ struct sockaddr_in srvAddr;
+ struct sockaddr_in cliAddr;
+ unsigned int srvAddrLen;
+ unsigned int cliAddrLen;
+ char wrkBuf[4096];
+ ssize_t nRead;
+ int opt;
+ int sleeptime = 0;
+ char *targetIP = NULL;
+ int targetPort = -1;
+
+ while((opt = getopt(argc, argv, "t:p:f:s:")) != -1) {
+ switch (opt) {
+ case 's':
+ sleeptime = atoi(optarg);
+ break;
+ case 't':
+ targetIP = optarg;
+ break;
+ case 'p':
+ targetPort = atoi(optarg);
+ break;
+ case 'f':
+ if(!strcmp(optarg, "-")) {
+ fdf = 1;
+ } else {
+ fdf = open(optarg, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR|S_IWUSR);
+ if(fdf == -1) errout(argv[3]);
+ }
+ break;
+ default:
+ fprintf(stderr, "invalid option '%c' or value missing - terminating...\n", opt);
+ usage();
+ break;
+ }
+ }
+
+ if(targetIP == NULL) {
+ fprintf(stderr, "-t parameter missing -- terminating\n");
+ usage();
+ }
+ if(targetPort == -1) {
+ fprintf(stderr, "-p parameter missing -- terminating\n");
+ usage();
+ }
+ if(fdf == -1) {
+ fprintf(stderr, "-f parameter missing -- terminating\n");
+ usage();
+ }
+
+ if(sleeptime) {
+ printf("minitcpsrv: deliberate sleep of %d seconds\n", sleeptime);
+ sleep(sleeptime);
+ printf("minitcpsrv: end sleep\n");
+ }
+
+ fds = socket(AF_INET, SOCK_STREAM, 0);
+ srvAddr.sin_family = AF_INET;
+ srvAddr.sin_addr.s_addr = inet_addr(targetIP);
+ srvAddr.sin_port = htons(targetPort);
+ srvAddrLen = sizeof(srvAddr);
+ if(bind(fds, (struct sockaddr *)&srvAddr, srvAddrLen) != 0)
+ errout("bind");
+ if(listen(fds, 20) != 0) errout("listen");
+ cliAddrLen = sizeof(cliAddr);
+
+ fdc = accept(fds, (struct sockaddr *)&cliAddr, &cliAddrLen);
+ while(1) {
+ nRead = read(fdc, wrkBuf, sizeof(wrkBuf));
+ if(nRead == 0) break;
+ if(write(fdf, wrkBuf, nRead) != nRead)
+ errout("write");
+ }
+ /* let the OS do the cleanup */
+ fprintf(stderr, "minitcpsrv terminates itself\n");
+ return 0;
+}
diff --git a/tests/mmanon_both_modes_compatible.sh b/tests/mmanon_both_modes_compatible.sh
new file mode 100755
index 0000000..f54477b
--- /dev/null
+++ b/tests/mmanon_both_modes_compatible.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.enable="on" ipv4.mode="zero" ipv4.bits="32" ipv6.bits="128" ipv6.anonmode="zero" ipv6.enable="on")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8 space 61:34:ad::7:F
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: abf:3:002::500F:ce 1.1.1.9\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' 0:0:0:0:0:0:0:0
+ 0.0.0.0 space 0:0:0:0:0:0:0:0
+ 0.0.0.0
+ 0:0:0:0:0:0:0:0 0.0.0.0'
+cmp_exact
+exit_test
diff --git a/tests/mmanon_ipv6_port.sh b/tests/mmanon_ipv6_port.sh
new file mode 100755
index 0000000..8ebbd6c
--- /dev/null
+++ b/tests/mmanon_ipv6_port.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv6.anonmode="zero")
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:c820:1180:c84c:ad3f:4024:d991:ec2e:4922
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:c820:1180:c84c:ad3f:4024:d991:ec2e
+<129>Mar 10 01:00:00 172.20.245.8 tag: [1a00:c820:1180:c84c:ad3f:4024:d991:ec2e]:4922
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:c820:1180:c84c:ad3f::d991:ec2e:4922
+<129>Mar 10 01:00:00 172.20.245.8 tag: [1a00:c820:1180:c84c:ad3f::d991:ec2e]:4922
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:c820:1180:c84c:ad3f::d991:ec2e:49225
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:4922:4922:c84c:ad3f::d991:ec2e:49225
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:4922:1180:c84c:ad3f::d991:4922:49225
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:c820:49225:c84c:ad3f::d991:ec2e:49225\""
+
+# see this github comment on limits of IP address detection:
+# https://github.com/rsyslog/rsyslog/issues/4856#issuecomment-1108445473
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' asdfghjk
+ 1a00:c820:0:0:0:0:0:0:4922
+ 1a00:c820:0:0:0:0:0:0
+ [1a00:c820:0:0:0:0:0:0]:4922
+ 1a00:c820:1180:0:0:0:0:0:0
+ [1a00:c820:0:0:0:0:0:0]:4922
+ 1a00:c820:0:0:0:0:0:0:49225
+ 1a00:4922:0:0:0:0:0:0:49225
+ 1a00:4922:0:0:0:0:0:0:49225
+ 1a00:c820:49225:c84c:0:0:0:0:0:0:49225'
+cmp_exact
+exit_test
diff --git a/tests/mmanon_random_128_ipv6.sh b/tests/mmanon_random_128_ipv6.sh
new file mode 100755
index 0000000..453bfb2
--- /dev/null
+++ b/tests/mmanon_random_128_ipv6.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+template(name="filename" type="string" string="'${RSYSLOG_DYNNAME}.'%syslogtag%.log")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv6.anonmode="random" ipv6.bits="128" ipv6.enable="on")
+ action(type="omfile" dynafile="filename" template="outfmt")
+}'
+
+echo 'Since this test tests randomization, there is a theoretical possibility of it failing even if rsyslog works correctly. Therefore, if the test unexpectedly fails try restarting it.'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 file1 33:45:DDD::4
+<129>Mar 10 01:00:00 172.20.245.8 file2 ::
+<129>Mar 10 01:00:00 172.20.245.8 file3 72:8374:adc7:47FF::43:0:1AFE
+<129>Mar 10 01:00:00 172.20.245.8 file4 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+<129>Mar 10 01:00:00 172.20.245.8 file5 72:8374:adc7:47FF::43:0:1AFE\""
+
+shutdown_when_empty
+wait_shutdown
+echo ' 33:45:DDD::4' | cmp - ${RSYSLOG_DYNNAME}.file1.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file1.log is:"
+ cat ${RSYSLOG_DYNNAME}.file1.log
+ error_exit 1
+fi;
+
+echo ' ::' | cmp - ${RSYSLOG_DYNNAME}.file2.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file2.log is:"
+ cat ${RSYSLOG_DYNNAME}.file2.log
+ error_exit 1
+fi;
+
+echo ' 72:8374:adc7:47FF::43:0:1AFE' | cmp - ${RSYSLOG_DYNNAME}.file3.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file3.log is:"
+ cat ${RSYSLOG_DYNNAME}.file3.log
+ error_exit 1
+fi;
+
+echo ' FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF' | cmp - ${RSYSLOG_DYNNAME}.file4.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file4.log is:"
+ cat ${RSYSLOG_DYNNAME}.file4.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file3.log ${RSYSLOG_DYNNAME}.file5.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-addresses generated, ${RSYSLOG_DYNNAME}.file3.log and ${RSYSLOG_DYNNAME}.file5.log are:"
+ cat ${RSYSLOG_DYNNAME}.file3.log
+ cat ${RSYSLOG_DYNNAME}.file5.log
+ error_exit 1
+fi;
+
+rm -f ${RSYSLOG_DYNNAME}.*.log
+exit_test
diff --git a/tests/mmanon_random_32_ipv4.sh b/tests/mmanon_random_32_ipv4.sh
new file mode 100755
index 0000000..2479df9
--- /dev/null
+++ b/tests/mmanon_random_32_ipv4.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+template(name="filename" type="string" string="'${RSYSLOG_DYNNAME}'.%syslogtag%.log")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.mode="random" ipv4.bits="32")
+ action(type="omfile" dynafile="filename" template="outfmt")
+}'
+
+echo 'Since this test tests randomization, there is a theoretical possibility of it failing even if rsyslog works correctly. Therefore, if the test unexpectedly fails try restarting it.'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 file1 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 file2 0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 file3 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 file4 111.1.1.8.
+<129>Mar 10 01:00:00 172.20.245.8 file5 172.0.234.255\""
+
+shutdown_when_empty
+wait_shutdown
+echo ' 1.1.1.8' | cmp - ${RSYSLOG_DYNNAME}.file1.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file1.log is:"
+ cat ${RSYSLOG_DYNNAME}.file1.log
+ error_exit 1
+fi;
+
+echo ' 0.0.0.0' | cmp - ${RSYSLOG_DYNNAME}.file2.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file2.log is:"
+ cat ${RSYSLOG_DYNNAME}.file2.log
+ error_exit 1
+fi;
+
+echo ' 172.0.234.255' | cmp - ${RSYSLOG_DYNNAME}.file3.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file3.log is:"
+ cat ${RSYSLOG_DYNNAME}.file3.log
+ error_exit 1
+fi;
+
+echo ' 111.1.1.8.' | cmp - ${RSYSLOG_DYNNAME}.file4.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file4.log is:"
+ cat ${RSYSLOG_DYNNAME}.file4.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file3.log ${RSYSLOG_DYNNAME}.file5.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-addresses generated, ${RSYSLOG_DYNNAME}.file3.log and ${RSYSLOG_DYNNAME}.file5.log are:"
+ cat ${RSYSLOG_DYNNAME}.file3.log
+ cat ${RSYSLOG_DYNNAME}.file5.log
+ error_exit 1
+fi;
+
+rm -f ${RSYSLOG_DYNNAME}.*.log
+exit_test
diff --git a/tests/mmanon_random_cons_128_ipembedded.sh b/tests/mmanon_random_cons_128_ipembedded.sh
new file mode 100755
index 0000000..75d7019
--- /dev/null
+++ b/tests/mmanon_random_cons_128_ipembedded.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+template(name="filename" type="string" string="'${RSYSLOG_DYNNAME}'.%syslogtag%.log")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv6.enable="off" ipv4.enable="off" embeddedipv4.anonmode="random-consistent" embeddedipv4.bits="128")
+ action(type="omfile" dynafile="filename" template="outfmt")
+}'
+
+echo 'Since this test tests randomization, there is a theoretical possibility of it failing even if rsyslog works correctly. Therefore, if the test unexpectedly fails try restarting it.'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 file1 33:45:DDD::4.123.123.3
+<129>Mar 10 01:00:00 172.20.245.8 file2 ::0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 file6 ::0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 file3 72:8374:adc7:47FF::43:0.34.225.1
+<129>Mar 10 01:00:00 172.20.245.8 file4 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255
+<129>Mar 10 01:00:00 172.20.245.8 file5 72:8374:adc7:47FF::43:0.34.225.1\""
+
+shutdown_when_empty
+wait_shutdown
+echo ' 33:45:DDD::4' | cmp - ${RSYSLOG_DYNNAME}.file1.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file1.log is:"
+ cat ${RSYSLOG_DYNNAME}.file1.log
+ error_exit 1
+fi;
+
+echo ' ::' | cmp - ${RSYSLOG_DYNNAME}.file2.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file2.log is:"
+ cat ${RSYSLOG_DYNNAME}.file2.log
+ error_exit 1
+fi;
+
+echo ' 72:8374:adc7:47FF::43:0:1AFE' | cmp - ${RSYSLOG_DYNNAME}.file3.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file3.log is:"
+ cat ${RSYSLOG_DYNNAME}.file3.log
+ error_exit 1
+fi;
+
+echo ' FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF' | cmp - ${RSYSLOG_DYNNAME}.file4.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file4.log is:"
+ cat ${RSYSLOG_DYNNAME}.file4.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file3.log ${RSYSLOG_DYNNAME}.file5.log >/dev/null
+if [ ! $? -eq 0 ]; then
+ echo "invalidly unequal ip-addresses generated, ${RSYSLOG_DYNNAME}.file3.log and ${RSYSLOG_DYNNAME}.file5.log are:"
+ cat ${RSYSLOG_DYNNAME}.file3.log
+ cat ${RSYSLOG_DYNNAME}.file5.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file2.log ${RSYSLOG_DYNNAME}.file6.log >/dev/null
+if [ ! $? -eq 0 ]; then
+ echo "invalidly unequal ip-addresses generated, ${RSYSLOG_DYNNAME}.file1.log and ${RSYSLOG_DYNNAME}.file6.log are:"
+ cat ${RSYSLOG_DYNNAME}.file1.log
+ cat ${RSYSLOG_DYNNAME}.file6.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file4.log ${RSYSLOG_DYNNAME}.file5.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-addresses generated, ${RSYSLOG_DYNNAME}.file4.log and ${RSYSLOG_DYNNAME}.file5.log are:"
+ cat ${RSYSLOG_DYNNAME}.file4.log
+ cat ${RSYSLOG_DYNNAME}.file5.log
+ error_exit 1
+fi;
+
+rm -f ${RSYSLOG_DYNNAME}.*.log
+exit_test
diff --git a/tests/mmanon_random_cons_128_ipv6.sh b/tests/mmanon_random_cons_128_ipv6.sh
new file mode 100755
index 0000000..3deddbe
--- /dev/null
+++ b/tests/mmanon_random_cons_128_ipv6.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+template(name="filename" type="string" string="'${RSYSLOG_DYNNAME}'.%syslogtag%.log")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv6.anonmode="random-consistent" ipv6.bits="128")
+ action(type="omfile" dynafile="filename" template="outfmt")
+}'
+
+echo 'Since this test tests randomization, there is a theoretical possibility of it failing even if rsyslog works correctly. Therefore, if the test unexpectedly fails try restarting it.'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 file1 33:45:DDD::4
+<129>Mar 10 01:00:00 172.20.245.8 file2 ::
+<129>Mar 10 01:00:00 172.20.245.8 file6 ::
+<129>Mar 10 01:00:00 172.20.245.8 file3 72:8374:adc7:47FF::43:0:1AFE
+<129>Mar 10 01:00:00 172.20.245.8 file4 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+<129>Mar 10 01:00:00 172.20.245.8 file5 72:8374:adc7:47FF::43:0:1AFE\""
+
+shutdown_when_empty
+wait_shutdown
+echo ' 33:45:DDD::4' | cmp - ${RSYSLOG_DYNNAME}.file1.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file1.log is:"
+ cat ${RSYSLOG_DYNNAME}.file1.log
+ error_exit 1
+fi;
+
+echo ' ::' | cmp - ${RSYSLOG_DYNNAME}.file2.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file2.log is:"
+ cat ${RSYSLOG_DYNNAME}.file2.log
+ error_exit 1
+fi;
+
+echo ' 72:8374:adc7:47FF::43:0:1AFE' | cmp - ${RSYSLOG_DYNNAME}.file3.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file3.log is:"
+ cat ${RSYSLOG_DYNNAME}.file3.log
+ error_exit 1
+fi;
+
+echo ' FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF' | cmp - ${RSYSLOG_DYNNAME}.file4.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file4.log is:"
+ cat ${RSYSLOG_DYNNAME}.file4.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file3.log ${RSYSLOG_DYNNAME}.file5.log >/dev/null
+if [ ! $? -eq 0 ]; then
+ echo "invalidly unequal ip-addresses generated, ${RSYSLOG_DYNNAME}.file3.log and ${RSYSLOG_DYNNAME}.file5.log are:"
+ cat ${RSYSLOG_DYNNAME}.file3.log
+ cat ${RSYSLOG_DYNNAME}.file5.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file2.log ${RSYSLOG_DYNNAME}.file6.log >/dev/null
+if [ ! $? -eq 0 ]; then
+ echo "invalidly unequal ip-addresses generated, ${RSYSLOG_DYNNAME}.file1.log and ${RSYSLOG_DYNNAME}.file6.log are:"
+ cat ${RSYSLOG_DYNNAME}.file1.log
+ cat ${RSYSLOG_DYNNAME}.file6.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file4.log ${RSYSLOG_DYNNAME}.file5.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-addresses generated, ${RSYSLOG_DYNNAME}.file4.log and ${RSYSLOG_DYNNAME}.file5.log are:"
+ cat ${RSYSLOG_DYNNAME}.file4.log
+ cat ${RSYSLOG_DYNNAME}.file5.log
+ error_exit 1
+fi;
+
+rm -f ${RSYSLOG_DYNNAME}.*.log
+exit_test
diff --git a/tests/mmanon_random_cons_32_ipv4.sh b/tests/mmanon_random_cons_32_ipv4.sh
new file mode 100755
index 0000000..f9fb6f5
--- /dev/null
+++ b/tests/mmanon_random_cons_32_ipv4.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+template(name="filename" type="string" string="'$RSYSLOG_DYNNAME'.%syslogtag%.log")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.mode="random-consistent" ipv4.bits="32")
+ action(type="omfile" dynafile="filename" template="outfmt")
+}'
+
+echo 'Since this test tests randomization, there is a theoretical possibility of it failing even if rsyslog works correctly. Therefore, if the test unexpectedly fails try restarting it.'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 file1 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 file2 0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 file3 0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 file4 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 file5 172.1.234.255
+<129>Mar 10 01:00:00 172.20.245.8 file6 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 file7 111.1.1.8.
+<129>Mar 10 01:00:00 172.20.245.8 file8 1.1.1.8\""
+
+shutdown_when_empty
+wait_shutdown
+echo ' 1.1.1.8' | cmp - ${RSYSLOG_DYNNAME}.file1.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file1.log is:"
+ cat ${RSYSLOG_DYNNAME}.file1.log
+ error_exit 1
+fi;
+
+echo ' 0.0.0.0' | cmp - ${RSYSLOG_DYNNAME}.file2.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file2.log is:"
+ cat ${RSYSLOG_DYNNAME}.file2.log
+ error_exit 1
+fi;
+
+echo ' 172.0.234.255' | cmp - ${RSYSLOG_DYNNAME}.file4.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file4.log is:"
+ cat ${RSYSLOG_DYNNAME}.file4.log
+ error_exit 1
+fi;
+
+echo ' 111.1.1.8.' | cmp - ${RSYSLOG_DYNNAME}.file7.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file7.log is:"
+ cat ${RSYSLOG_DYNNAME}.file7.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file1.log ${RSYSLOG_DYNNAME}.file6.log >/dev/null
+if [ ! $? -eq 0 ]; then
+ echo "invalidly unequal ip-addresses generated, ${RSYSLOG_DYNNAME}.file1.log and ${RSYSLOG_DYNNAME}.file6.log are:"
+ cat ${RSYSLOG_DYNNAME}.file1.log
+ cat ${RSYSLOG_DYNNAME}.file6.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file6.log ${RSYSLOG_DYNNAME}.file8.log >/dev/null
+if [ ! $? -eq 0 ]; then
+ echo "invalidly unequal ip-addresses generated, ${RSYSLOG_DYNNAME}.file6.log and ${RSYSLOG_DYNNAME}.file8.log are:"
+ cat ${RSYSLOG_DYNNAME}.file6.log
+ cat ${RSYSLOG_DYNNAME}.file8.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file2.log ${RSYSLOG_DYNNAME}.file3.log >/dev/null
+if [ ! $? -eq 0 ]; then
+ echo "invalidly unequal ip-addresses generated, ${RSYSLOG_DYNNAME}.file2.log and ${RSYSLOG_DYNNAME}.file3.log are:"
+ cat ${RSYSLOG_DYNNAME}.file2.log
+ cat ${RSYSLOG_DYNNAME}.file3.log
+ error_exit 1
+fi;
+
+cmp ${RSYSLOG_DYNNAME}.file4.log ${RSYSLOG_DYNNAME}.file5.log >/dev/null
+if [ ! $? -eq 1 ]; then
+ echo "invalidly equal ip-addresses generated, ${RSYSLOG_DYNNAME}.file4.log and ${RSYSLOG_DYNNAME}.file5.log are:"
+ cat ${RSYSLOG_DYNNAME}.file4.log
+ cat ${RSYSLOG_DYNNAME}.file5.log
+ error_exit 1
+fi;
+
+rm -f ${RSYSLOG_DYNNAME}.*.log
+exit_test
diff --git a/tests/mmanon_recognize_ipembedded.sh b/tests/mmanon_recognize_ipembedded.sh
new file mode 100755
index 0000000..2b7efa0
--- /dev/null
+++ b/tests/mmanon_recognize_ipembedded.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.enable="off" ipv6.enable="off" embeddedipv4.bits="128" embeddedipv4.anonmode="zero")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk
+<129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 61:34:ad::7:F aa:ff43::756:172.2.3.4
+<129>Mar 10 01:00:00 172.20.245.8 tag: ::
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0::
+<129>Mar 10 01:00:00 172.20.245.8 tag: ::0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45:1:1:1:0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45::1:1:0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45:1:1:1:1:0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45:1:1:1::1:0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45:0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45::. test
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45::1.2.3.4 test
+<129>Mar 10 01:00:00 172.20.245.8 tag: *13:abd:45::ac.2.3.5* test
+<129>Mar 10 01:00:00 172.20.245.8 tag: ewirnwem aa:ff43:756:99:ff:445:cc.1.2.3.4
+<129>Mar 10 01:00:00 172.20.245.8 tag: aa::ff:bb:122:0:44.1.23.4.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 12:12345::a.3.4.12.7
+<129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:172.1.1.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 72:8374:adc7:47FF::43:172.1.1.0stillnoblank
+<129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:172.1.1.0stillnoblank\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' asdfghjk
+ 0:0:0:0:0:0:0.0.0.0
+ 61:34:ad::7:F 0:0:0:0:0:0:0.0.0.0
+ ::
+ 0::
+ 0:0:0:0:0:0:0.0.0.0
+ 0:0:0:0:0:0:0.0.0.0
+ 0:0:0:0:0:0:0.0.0.0
+ 13:0:0:0:0:0:0:0.0.0.0
+ 13:abd:0:0:0:0:0:0:0.0.0.0
+ 13:abd:45:0.0.0.0
+ 13:abd:45::. test
+ 0:0:0:0:0:0:0.0.0.0 test
+ *13:abd:45::ac.2.3.5* test
+ ewirnwem aa:ff43:756:99:ff:445:cc.1.2.3.4
+ 0:0:0:0:0:0:0.0.0.0.0
+ 12:12345::a.3.4.12.7
+ textnoblank0:0:0:0:0:0:0.0.0.0
+ 0:0:0:0:0:0:0.0.0.0stillnoblank
+ textnoblank0:0:0:0:0:0:0.0.0.0stillnoblank'
+cmp_exact
+exit_test
diff --git a/tests/mmanon_recognize_ipv4.sh b/tests/mmanon_recognize_ipv4.sh
new file mode 100755
index 0000000..05c9eff
--- /dev/null
+++ b/tests/mmanon_recognize_ipv4.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog"
+
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" mode="zero" ipv4.bits="32")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk
+<129>Mar 10 01:00:00 172.20.245.8 tag: before 172.9.6.4
+<129>Mar 10 01:00:00 172.20.245.8 tag: 75.123.123.0 after
+<129>Mar 10 01:00:00 172.20.245.8 tag: before 181.23.1.4 after
+<129>Mar 10 01:00:00 172.20.245.8 tag: nothingnothingnothing
+<129>Mar 10 01:00:00 172.20.245.8 tag: before 181.23.1.4 after 172.1.3.4
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.9
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.2.3.4.5.6.7.8.76
+<129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.225.225.225
+<129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 3.4.5.6
+<129>Mar 10 01:00:00 172.20.245.8 tag: 256.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1....1....1....8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1..1..1..8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1..1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1..1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1..8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1111.1.1.8.1
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.1
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.
+<129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank1.1.1.9stillnoblank\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' asdfghjk
+ before 0.0.0.0
+ 0.0.0.0 after
+ before 0.0.0.0 after
+ nothingnothingnothing
+ before 0.0.0.0 after 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0.0.0.0.0.76
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 20.0.0.0
+ 1....1....1....8
+ 1..1..1..8
+ 1..1.1.8
+ 1.1..1.8
+ 1.1.1..8
+ 10.0.0.0.1
+ 0.0.0.0.1
+ 0.0.0.0.
+ textnoblank0.0.0.0stillnoblank'
+cmp_exact
+exit_test
diff --git a/tests/mmanon_recognize_ipv6.sh b/tests/mmanon_recognize_ipv6.sh
new file mode 100755
index 0000000..b7ea773
--- /dev/null
+++ b/tests/mmanon_recognize_ipv6.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.enable="off" ipv6.enable="on" ipv6.bits="128" ipv6.anonmode="zero")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk
+<129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+<129>Mar 10 01:00:00 172.20.245.8 tag: 61:34:ad::7:F aa:ff43::756:99:0
+<129>Mar 10 01:00:00 172.20.245.8 tag: ::
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0::
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45:
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45::. test
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45::* test
+<129>Mar 10 01:00:00 172.20.245.8 tag: *13:abd:45::* test
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45:* test
+<129>Mar 10 01:00:00 172.20.245.8 tag: ewirnwemaa:ff43::756:99:0
+<129>Mar 10 01:00:00 172.20.245.8 tag: a::, cc:: LLL
+<129>Mar 10 01:00:00 172.20.245.8 tag: 12:12345::a
+<129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:0:1AFE
+<129>Mar 10 01:00:00 172.20.245.8 tag: 72:8374:adc7:47FF::43:0:1AFEstillnoblank
+<129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:0:1AFEstillnoblank\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' asdfghjk
+ 0:0:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0
+ 13:abd:45:
+ 0:0:0:0:0:0:0:0. test
+ 0:0:0:0:0:0:0:0* test
+ *0:0:0:0:0:0:0:0* test
+ 13:abd:45:* test
+ ewirnwem0:0:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0, 0:0:0:0:0:0:0:0 LLL
+ 12:10:0:0:0:0:0:0:0
+ textnoblank0:0:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0stillnoblank
+ textnoblank0:0:0:0:0:0:0:0stillnoblank'
+cmp_exact
+exit_test
diff --git a/tests/mmanon_simple_12_ipv4.sh b/tests/mmanon_simple_12_ipv4.sh
new file mode 100755
index 0000000..24d1126
--- /dev/null
+++ b/tests/mmanon_simple_12_ipv4.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.bits="12" ipv4.mode="simple")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.\""
+
+shutdown_when_empty
+wait_shutdown
+echo ' 1.1.x.x
+ 0.0.x.x
+ 172.0.xxx.xxx
+ 111.1.x.x.' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+grep 'invalid number of ipv4 bits in simple mode, corrected to 16' ${RSYSLOG2_OUT_LOG} > /dev/null
+if [ $? -ne 0 ]; then
+ echo "invalid response generated, ${RSYSLOG2_OUT_LOG} is:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/mmanon_simple_33_ipv4.sh b/tests/mmanon_simple_33_ipv4.sh
new file mode 100755
index 0000000..4190b92
--- /dev/null
+++ b/tests/mmanon_simple_33_ipv4.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.bits="33" ipv4.mode="simple" ipv4.replacechar="*")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk
+<129>Mar 10 01:00:00 172.20.245.8 tag: before 172.9.6.4
+<129>Mar 10 01:00:00 172.20.245.8 tag: 75.123.123.0 after
+<129>Mar 10 01:00:00 172.20.245.8 tag: before 181.23.1.4 after
+<129>Mar 10 01:00:00 172.20.245.8 tag: nothingnothingnothing
+<129>Mar 10 01:00:00 172.20.245.8 tag: before 181.23.1.4 after 172.1.3.45
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.12.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.9
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.2.3.4.5.6.7.8.76
+<129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.225.225.225
+<129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 3.4.5.6
+<129>Mar 10 01:00:00 172.20.245.8 tag: 256.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1....1....1....8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1..1..1..8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1..1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1..1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1..8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1111.1.1.8.1
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.1
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.
+<129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank1.1.31.9stillnoblank\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' asdfghjk
+ before ***.*.*.*
+ **.***.***.* after
+ before ***.**.*.* after
+ nothingnothingnothing
+ before ***.**.*.* after ***.*.*.**
+ *.*.*.*
+ *.**.*.*
+ *.*.*.*
+ *.*.*.*
+ *.*.*.*.*.*.*.*.76
+ ***.*.***.***
+ *.*.*.*
+ *.***.***.***
+ ***.*.***.***
+ *.*.*.*
+ ***.*.*.*
+ 1....1....1....8
+ 1..1..1..8
+ 1..1.1.8
+ 1.1..1.8
+ 1.1.1..8
+ ****.*.*.*.1
+ ***.*.*.*.1
+ ***.*.*.*.
+ textnoblank*.*.**.*stillnoblank'
+cmp_exact
+
+grep 'invalid number of ipv4.bits (33), corrected to 32' ${RSYSLOG2_OUT_LOG} > /dev/null
+if [ $? -ne 0 ]; then
+ echo "invalid response generated, ${RSYSLOG2_OUT_LOG} is:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/mmanon_simple_8_ipv4.sh b/tests/mmanon_simple_8_ipv4.sh
new file mode 100755
index 0000000..192f7ff
--- /dev/null
+++ b/tests/mmanon_simple_8_ipv4.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.bits="8" ipv4.mode="simple")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' 1.1.1.x
+ 0.0.0.x
+ 172.0.234.xxx
+ 111.1.1.x.'
+cmp_exact
+exit_test
diff --git a/tests/mmanon_simple_mallformed_ipv4.sh b/tests/mmanon_simple_mallformed_ipv4.sh
new file mode 100755
index 0000000..7ef8899
--- /dev/null
+++ b/tests/mmanon_simple_mallformed_ipv4.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# add 2022-07-28 by Andre Lorbach, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+#export USE_VALGRIND="YES" # this test only makes sense with valgrind enabled
+#export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes"
+
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog"
+
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.bits="32" ipv4.mode="simple")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: 165874883373.1.15599155266856607338.91@whatever
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.165874883373.15599155266856607338.91@whatever
+<129>Mar 10 01:00:00 172.20.245.8 tag: 15599155266856607338.165874883373.1.91@whatever
+<129>Mar 10 01:00:00 172.20.245.8 tag: 91.165874883373.1.15599155266856607338.@whatever\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' 165874883373.1.15599155266856607338.91@whatever
+ 1.165874883373.15599155266856607338.91@whatever
+ 15599155266856607338.165874883373.1.91@whatever
+ 91.165874883373.1.15599155266856607338.@whatever'
+cmp_exact
+exit_test
diff --git a/tests/mmanon_with_debug.sh b/tests/mmanon_with_debug.sh
new file mode 100755
index 0000000..13678a2
--- /dev/null
+++ b/tests/mmanon_with_debug.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on all flavors of Solaris."
+export RSYSLOG_DEBUG="debug nostdout"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog"
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" mode="zero" ipv4.bits="32")
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk
+<129>Mar 10 01:00:00 172.20.245.8 tag: before 172.9.6.4
+<129>Mar 10 01:00:00 172.20.245.8 tag: 75.123.123.0 after
+<129>Mar 10 01:00:00 172.20.245.8 tag: before 181.23.1.4 after
+<129>Mar 10 01:00:00 172.20.245.8 tag: nothingnothingnothing
+<129>Mar 10 01:00:00 172.20.245.8 tag: before 181.23.1.4 after 172.1.3.4
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.9
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.2.3.4.5.6.7.8.76
+<129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.225.225.225
+<129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 3.4.5.6
+<129>Mar 10 01:00:00 172.20.245.8 tag: 256.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1....1....1....8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1..1..1..8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1..1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1..1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1..8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 1111.1.1.8.1
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.1
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.
+<129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank1.1.1.9stillnoblank\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' asdfghjk
+ before 0.0.0.0
+ 0.0.0.0 after
+ before 0.0.0.0 after
+ nothingnothingnothing
+ before 0.0.0.0 after 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0.0.0.0.0.76
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 20.0.0.0
+ 1....1....1....8
+ 1..1..1..8
+ 1..1.1.8
+ 1.1..1.8
+ 1.1.1..8
+ 10.0.0.0.1
+ 0.0.0.0.1
+ 0.0.0.0.
+ textnoblank0.0.0.0stillnoblank'
+cmp_exact
+if [ ! -e "$RSYSLOG_DEBUGLOG" ]; then
+ echo "error: file '$RSYSLOG_DEBUGLOG' (Debuglog) not found (should be generated)"
+ error_exit 1
+fi
+exit_test
diff --git a/tests/mmanon_zero_128_ipv6.sh b/tests/mmanon_zero_128_ipv6.sh
new file mode 100755
index 0000000..f410dfc
--- /dev/null
+++ b/tests/mmanon_zero_128_ipv6.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv6.bits="129" ipv6.anonmode="zero")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk
+<129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+<129>Mar 10 01:00:00 172.20.245.8 tag: 61:34:ad::7:F aa:ff43::756:99:0
+<129>Mar 10 01:00:00 172.20.245.8 tag: ::
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0::
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45:
+<129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:0:1AFEstillnoblank\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' asdfghjk
+ 0:0:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0
+ 13:abd:45:
+ textnoblank0:0:0:0:0:0:0:0stillnoblank'
+cmp_exact
+
+grep 'invalid number of ipv6.bits (129), corrected to 128' ${RSYSLOG2_OUT_LOG} > /dev/null
+if [ $? -ne 0 ]; then
+ echo "invalid correction of bits parameter generated, ${RSYSLOG2_OUT_LOG} is:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/mmanon_zero_12_ipv4.sh b/tests/mmanon_zero_12_ipv4.sh
new file mode 100755
index 0000000..b852f10
--- /dev/null
+++ b/tests/mmanon_zero_12_ipv4.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.bits="12")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' 1.1.0.0
+ 0.0.0.0
+ 172.0.224.0
+ 111.1.0.0.'
+cmp_exact
+exit_test
diff --git a/tests/mmanon_zero_33_ipv4.sh b/tests/mmanon_zero_33_ipv4.sh
new file mode 100755
index 0000000..e70455d
--- /dev/null
+++ b/tests/mmanon_zero_33_ipv4.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.bits="33")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0
+ 0.0.0.0.'
+cmp_exact
+
+grep 'invalid number of ipv4.bits (33), corrected to 32' ${RSYSLOG2_OUT_LOG} > /dev/null
+if [ $? -ne 0 ]; then
+ echo "invalid response generated, ${RSYSLOG2_OUT_LOG} is:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi;
+
+
+exit_test
diff --git a/tests/mmanon_zero_50_ipv6.sh b/tests/mmanon_zero_50_ipv6.sh
new file mode 100755
index 0000000..ee8e7dd
--- /dev/null
+++ b/tests/mmanon_zero_50_ipv6.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv6.bits="50" ipv6.anonmode="zero")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk
+<129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+<129>Mar 10 01:00:00 172.20.245.8 tag: 61:34:ad::7:F aa:ff43::756:99:0
+<129>Mar 10 01:00:00 172.20.245.8 tag: ::
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0::
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45:
+<129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:0:1AFEstillnoblank\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' asdfghjk
+ ffff:ffff:ffff:ffff:fffc:0:0:0
+ 61:34:ad:0:0:0:0:0 aa:ff43:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0
+ 13:abd:45:
+ textnoblank72:8374:adc7:47ff:0:0:0:0stillnoblank'
+cmp_exact
+exit_test
diff --git a/tests/mmanon_zero_64_ipv6.sh b/tests/mmanon_zero_64_ipv6.sh
new file mode 100755
index 0000000..8f5f537
--- /dev/null
+++ b/tests/mmanon_zero_64_ipv6.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv6.bits="64" ipv6.anonmode="zero")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk
+<129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+<129>Mar 10 01:00:00 172.20.245.8 tag: 61:34:ad::7:F aa:ff43::756:99:0
+<129>Mar 10 01:00:00 172.20.245.8 tag: ::
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0::
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45:
+<129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:0:1AFEstillnoblank\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' asdfghjk
+ ffff:ffff:ffff:ffff:0:0:0:0
+ 61:34:ad:0:0:0:0:0 aa:ff43:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0
+ 13:abd:45:
+ textnoblank72:8374:adc7:47ff:0:0:0:0stillnoblank'
+cmp_exact
+exit_test
diff --git a/tests/mmanon_zero_8_ipv4.sh b/tests/mmanon_zero_8_ipv4.sh
new file mode 100755
index 0000000..430c27f
--- /dev/null
+++ b/tests/mmanon_zero_8_ipv4.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon" ipv4.bits="8")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0
+<129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255
+<129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' 1.1.1.0
+ 0.0.0.0
+ 172.0.234.0
+ 111.1.1.0.'
+cmp_exact
+exit_test
diff --git a/tests/mmanon_zero_96_ipv6.sh b/tests/mmanon_zero_96_ipv6.sh
new file mode 100755
index 0000000..77793e3
--- /dev/null
+++ b/tests/mmanon_zero_96_ipv6.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmanon/.libs/mmanon")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmanon")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk
+<129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+<129>Mar 10 01:00:00 172.20.245.8 tag: 61:34:ad::7:F aa:ff43::756:99:0
+<129>Mar 10 01:00:00 172.20.245.8 tag: ::
+<129>Mar 10 01:00:00 172.20.245.8 tag: 0::
+<129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45:
+<129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:0:1AFEstillnoblank\""
+
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=' asdfghjk
+ ffff:ffff:0:0:0:0:0:0
+ 61:34:0:0:0:0:0:0 aa:ff43:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0
+ 0:0:0:0:0:0:0:0
+ 13:abd:45:
+ textnoblank72:8374:0:0:0:0:0:0stillnoblank'
+cmp_exact
+exit_test
diff --git a/tests/mmdarwin_errmsg_no_params.sh b/tests/mmdarwin_errmsg_no_params.sh
new file mode 100755
index 0000000..0e491f2
--- /dev/null
+++ b/tests/mmdarwin_errmsg_no_params.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-04-02 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/mmdarwin/.libs/mmdarwin")
+action(type="mmdarwin")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+ startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter 'socketpath' required but not specified"
+
+exit_test
diff --git a/tests/mmdarwin_errmsg_no_sock-vg.sh b/tests/mmdarwin_errmsg_no_sock-vg.sh
new file mode 100755
index 0000000..c480f86
--- /dev/null
+++ b/tests/mmdarwin_errmsg_no_sock-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# add 2019-04-02 by Rainer Gerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/mmdarwin_errmsg_no_sock.sh
diff --git a/tests/mmdarwin_errmsg_no_sock.sh b/tests/mmdarwin_errmsg_no_sock.sh
new file mode 100755
index 0000000..9a1cc6c
--- /dev/null
+++ b/tests/mmdarwin_errmsg_no_sock.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-04-02 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/mmdarwin/.libs/mmdarwin")
+action(type="mmdarwin" socketpath="/invalid" key="invalid" fields="invalid")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+ startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "error connecting to Darwin.*/invalid"
+
+exit_test
diff --git a/tests/mmdb-container-empty.sh b/tests/mmdb-container-empty.sh
new file mode 100755
index 0000000..a9e7e04
--- /dev/null
+++ b/tests/mmdb-container-empty.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!src_geoip%\n")
+
+module(load="../plugins/mmdblookup/.libs/mmdblookup" container="!")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmnormalize" rulebase=`echo $srcdir/mmdb.rb`)
+ action(type="mmdblookup" mmdbfile=`echo $srcdir/test.mmdb` key="$!ip" fields=":src_geoip!city_name:city" )
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+startup
+tcpflood -m 1 -j "202.106.0.20\ "
+shutdown_when_empty
+wait_shutdown
+content_check '{ "city_name": "Beijing" }'
+exit_test
diff --git a/tests/mmdb-container.sh b/tests/mmdb-container.sh
new file mode 100755
index 0000000..e824a06
--- /dev/null
+++ b/tests/mmdb-container.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!mmdb_root%\n")
+
+module(load="../plugins/mmdblookup/.libs/mmdblookup" container="!mmdb_root")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmnormalize" rulebase=`echo $srcdir/mmdb.rb`)
+ action(type="mmdblookup" mmdbfile=`echo $srcdir/test.mmdb` key="$!ip" fields="city" )
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+startup
+tcpflood -m 1 -j "202.106.0.20\ "
+shutdown_when_empty
+wait_shutdown
+content_check '{ "city": "Beijing" }'
+exit_test
diff --git a/tests/mmdb-multilevel-vg.sh b/tests/mmdb-multilevel-vg.sh
new file mode 100755
index 0000000..b6096b3
--- /dev/null
+++ b/tests/mmdb-multilevel-vg.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# we libmaxminddb, in packaged versions, has a small cosmetic memory leak,
+# thus we need a suppressions file:
+export RS_TESTBENCH_VALGRIND_EXTRA_OPTS="$RS_TESTBENCH_VALGRIND_EXTRA_OPTS --suppressions=$srcdir/libmaxmindb.supp"
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!iplocation%\n")
+
+module(load="../plugins/mmdblookup/.libs/mmdblookup")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmnormalize" rulebase="'$srcdir'/mmdb.rb")
+ # Uncomment this action when using the real GeoLite2 city database;
+ # we have not included it into the testbench for licensing concerns.
+ # action(type="mmdblookup" mmdbfile="/home/USR/GeoLite2-City_20170502/GeoLite2-City.mmdb" key="$!ip" fields=":city:!city!names!en" )
+ action(type="mmdblookup" mmdbfile="'$srcdir'/test.mmdb" key="$!ip" fields=":city_name:city" )
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}'
+startup_vg
+tcpflood -m 100 -j "202.106.0.20\ "
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+content_check '{ "city_name": "Beijing" }'
+exit_test
diff --git a/tests/mmdb-space.sh b/tests/mmdb-space.sh
new file mode 100755
index 0000000..797290e
--- /dev/null
+++ b/tests/mmdb-space.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# added 2014-11-17 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[mmdb.sh\]: test for mmdb
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout"
+#export RSYSLOG_DEBUGLOG="log"
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!iplocation%\n")
+
+module(load="../plugins/mmdblookup/.libs/mmdblookup")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmnormalize" rulebase="'$srcdir'/mmdb.rb")
+ action(type="mmdblookup" mmdbfile="'$srcdir'/with_space.mmdb" key="$!ip" fields="city" )
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+startup
+tcpflood -m 1 -j "202.106.0.20\ "
+shutdown_when_empty
+wait_shutdown
+content_check '{ "city": "Bei ing" }'
+exit_test
diff --git a/tests/mmdb-vg.sh b/tests/mmdb-vg.sh
new file mode 100755
index 0000000..b2f9079
--- /dev/null
+++ b/tests/mmdb-vg.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# we libmaxminddb, in packaged versions, has a small cosmetic memory leak,
+# thus we need a suppressions file:
+export RS_TESTBENCH_VALGRIND_EXTRA_OPTS="$RS_TESTBENCH_VALGRIND_EXTRA_OPTS --suppressions=$srcdir/libmaxmindb.supp"
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!iplocation%\n")
+
+module(load="../plugins/mmdblookup/.libs/mmdblookup")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmnormalize" rulebase="'$srcdir'/mmdb.rb")
+ action(type="mmdblookup" mmdbfile="'$srcdir'/test.mmdb" key="$!ip" fields="city" )
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}'
+startup_vg
+tcpflood -m 100 -j "202.106.0.20\ "
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+content_check '{ "city": "Beijing" }'
+exit_test
diff --git a/tests/mmdb.rb b/tests/mmdb.rb
new file mode 100644
index 0000000..38697a0
--- /dev/null
+++ b/tests/mmdb.rb
@@ -0,0 +1,3 @@
+version=2
+
+rule=: %ip:word% %remaining:word%
diff --git a/tests/mmdb.sh b/tests/mmdb.sh
new file mode 100755
index 0000000..473f7a0
--- /dev/null
+++ b/tests/mmdb.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# added 2014-11-17 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[mmdb.sh\]: test for mmdb
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout"
+#export RSYSLOG_DEBUGLOG="log"
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!iplocation%\n")
+
+module(load="../plugins/mmdblookup/.libs/mmdblookup")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmnormalize" rulebase=`echo $srcdir/mmdb.rb`)
+ action(type="mmdblookup" mmdbfile=`echo $srcdir/test.mmdb` key="$!ip" fields="city" )
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+startup
+tcpflood -m 1 -j "202.106.0.20\ "
+shutdown_when_empty
+wait_shutdown
+content_check '{ "city": "Beijing" }'
+exit_test
diff --git a/tests/mmexternal-InvldProg-vg.sh b/tests/mmexternal-InvldProg-vg.sh
new file mode 100755
index 0000000..7ce4e4c
--- /dev/null
+++ b/tests/mmexternal-InvldProg-vg.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# add 2017-12-29 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/mmexternal/.libs/mmexternal")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+set $!x = "a";
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+if $msg contains "msgnum:" then {
+ action(type="mmexternal" interface.input="fulljson"
+ binary="does/not/exist")
+}
+action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup_vg_noleak
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag:msgnum:1\""
+./msleep 500 # let the fork happen and report back!
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+grep 'failed to execute' $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/mmexternal-SegFault-empty-jroot-vg.sh b/tests/mmexternal-SegFault-empty-jroot-vg.sh
new file mode 100755
index 0000000..71e8e64
--- /dev/null
+++ b/tests/mmexternal-SegFault-empty-jroot-vg.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# add 2017-11-06 by PascalWithopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmexternal/.libs/mmexternal")
+
+template(name="outfmt" type="string" string="-%$!%-\n")
+
+if $msg contains "msgnum:" then {
+ action(type="mmexternal" interface.input="fulljson"
+ binary="'$PYTHON' '${srcdir}'/testsuites/mmexternal-SegFault-mm-python.py")
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup_vg
+injectmsg literal "<129>Mar 10 01:00:00 172.20.245.8 tag:msgnum:1"
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+export EXPECTED='-{ "sometag": "somevalue" }-'
+cmp_exact
+exit_test
diff --git a/tests/mmexternal-SegFault.sh b/tests/mmexternal-SegFault.sh
new file mode 100755
index 0000000..e538df4
--- /dev/null
+++ b/tests/mmexternal-SegFault.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# a case that actually caused a segfault
+# add 2017-11-06 by PascalWithopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmexternal/.libs/mmexternal")
+set $!x = "a";
+
+template(name="outfmt" type="string" string="-%$!%-\n")
+
+if $msg contains "msgnum:" then {
+ action(type="mmexternal" interface.input="fulljson"
+ binary="'$PYTHON' '${srcdir}'/testsuites/mmexternal-SegFault-mm-python.py")
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+startup
+injectmsg literal "<129>Mar 10 01:00:00 172.20.245.8 tag:msgnum:1"
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='-{ "x": "a", "sometag": "somevalue" }-'
+cmp_exact
+exit_test
diff --git a/tests/mmjsonparse-invalid-containerName.sh b/tests/mmjsonparse-invalid-containerName.sh
new file mode 100755
index 0000000..3488cd1
--- /dev/null
+++ b/tests/mmjsonparse-invalid-containerName.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2018-04-13 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/impstats/.libs/impstats" interval="300"
+ resetCounters="on" format="cee" ruleset="fooruleset" log.syslog="on")
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+
+action(name="fooname" type="mmjsonparse" container="foobar")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+grep "mmjsonparse: invalid container name 'foobar', name must start with" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+grep "impstats: ruleset 'fooruleset' not found - using default ruleset instead" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/mmjsonparse-w-o-cookie-multi-spaces.sh b/tests/mmjsonparse-w-o-cookie-multi-spaces.sh
new file mode 100755
index 0000000..a8862a0
--- /dev/null
+++ b/tests/mmjsonparse-w-o-cookie-multi-spaces.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# addd 2016-03-22 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!msgnum%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse" cookie="")
+if $parsesuccess == "OK" then {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+startup
+tcpflood -m $NUMMESSAGES "-j \" \""
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/mmjsonparse-w-o-cookie.sh b/tests/mmjsonparse-w-o-cookie.sh
new file mode 100755
index 0000000..0dcd78b
--- /dev/null
+++ b/tests/mmjsonparse-w-o-cookie.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# addd 2016-03-22 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!msgnum%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse" cookie="")
+if $parsesuccess == "OK" then {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+startup
+tcpflood -m $NUMMESSAGES "-j \" \""
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/mmjsonparse_cim.sh b/tests/mmjsonparse_cim.sh
new file mode 100755
index 0000000..702e678
--- /dev/null
+++ b/tests/mmjsonparse_cim.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# added 2014-07-15 by rgerhards
+# basic test for mmjsonparse module with "cim" cookie
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!cim!msgnum%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse" cookie="@cim:" container="!cim")
+if $parsesuccess == "OK" then {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -m $NUMMESSAGES -j "@cim: "
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/mmjsonparse_cim2.sh b/tests/mmjsonparse_cim2.sh
new file mode 100755
index 0000000..6086334
--- /dev/null
+++ b/tests/mmjsonparse_cim2.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# add 2018-04-16 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!cim!msgnum%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse" cookie="@cim:" container="$!cim")
+if $parsesuccess == "OK" then {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -m $NUMMESSAGES -j "@cim: "
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
+
diff --git a/tests/mmjsonparse_extra_data-vg.sh b/tests/mmjsonparse_extra_data-vg.sh
new file mode 100755
index 0000000..1b8a05c
--- /dev/null
+++ b/tests/mmjsonparse_extra_data-vg.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# ensure mmjsonparse works correctly if passed unparsable message
+# add 2018-11-05 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="-%msg%-\n")
+
+action(type="mmjsonparse" cookie="")
+if $parsesuccess == "OK" then {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+else if $parsesuccess == "FAIL" and $msg contains "param1" then {
+ action(type="omfile" file="'$RSYSLOG2_OUT_LOG'" template="outfmt")
+}
+'
+startup_vg
+tcpflood -m2 -M "\"{\\\"param1\\\":\\\"value1\\\"} data\""
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+check_file_not_exists $RSYSLOG_OUT_LOG
+export EXPECTED='-{"param1":"value1"} data-
+-{"param1":"value1"} data-'
+cmp_exact $RSYSLOG2_OUT_LOG
+exit_test
diff --git a/tests/mmjsonparse_localvar.sh b/tests/mmjsonparse_localvar.sh
new file mode 100755
index 0000000..7597b73
--- /dev/null
+++ b/tests/mmjsonparse_localvar.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# added 2018-04-16 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$.msgnum%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse" cookie="@cim:" container="$.")
+if $parsesuccess == "OK" then {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -m $NUMMESSAGES -j "@cim: "
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
+
diff --git a/tests/mmjsonparse_simple.sh b/tests/mmjsonparse_simple.sh
new file mode 100755
index 0000000..5419e8b
--- /dev/null
+++ b/tests/mmjsonparse_simple.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# added 2014-07-15 by rgerhards
+# basic test for mmjsonparse module with defaults
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!msgnum%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse")
+if $parsesuccess == "OK" then {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -m $NUMMESSAGES -j "@cee: "
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/mmkubernetes-basic-vg.sh b/tests/mmkubernetes-basic-vg.sh
new file mode 100755
index 0000000..fbd1be3
--- /dev/null
+++ b/tests/mmkubernetes-basic-vg.sh
@@ -0,0 +1,187 @@
+#!/bin/bash
+# added 2018-04-06 by richm, released under ASL 2.0
+#
+# Note: on buildbot VMs (where there is no environment cleanup), the
+# kubernetes test server may be kept running if the script aborts or
+# is aborted (buildbot master failure!) for some reason. As such we
+# execute it under "timeout" control, which ensure it always is
+# terminated. It's not a 100% great method, but hopefully does the
+# trick. -- rgerhards, 2018-07-21
+#export RSYSLOG_DEBUG="debug"
+USE_VALGRIND=true
+. ${srcdir:=.}/diag.sh init
+check_command_available timeout
+pwd=$( pwd )
+k8s_srv_port=$( get_free_port )
+generate_conf
+add_conf '
+global(workDirectory="'$RSYSLOG_DYNNAME.spool'")
+module(load="../plugins/impstats/.libs/impstats" interval="1"
+ log.file="'"$RSYSLOG_DYNNAME.spool"'/mmkubernetes-stats.log" log.syslog="off" format="cee")
+module(load="../plugins/imfile/.libs/imfile")
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../contrib/mmkubernetes/.libs/mmkubernetes")
+
+template(name="mmk8s_template" type="list") {
+ property(name="$!all-json-plain")
+ constant(value="\n")
+}
+
+input(type="imfile" file="'$RSYSLOG_DYNNAME.spool'/pod-*.log" tag="kubernetes" addmetadata="on")
+action(type="mmjsonparse" cookie="")
+action(type="mmkubernetes" busyretryinterval="1" token="dummy" kubernetesurl="http://localhost:'$k8s_srv_port'"
+ filenamerules=["rule=:'$pwd/$RSYSLOG_DYNNAME.spool'/%pod_name:char-to:.%.%container_hash:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log",
+ "rule=:'$pwd/$RSYSLOG_DYNNAME.spool'/%pod_name:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log"]
+)
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="mmk8s_template")
+'
+
+testsrv=mmk8s-test-server
+echo starting kubernetes \"emulator\"
+timeout 2m $PYTHON -u $srcdir/mmkubernetes_test_server.py $k8s_srv_port ${RSYSLOG_DYNNAME}${testsrv}.pid ${RSYSLOG_DYNNAME}${testsrv}.started > ${RSYSLOG_DYNNAME}.spool/mmk8s_srv.log 2>&1 &
+BGPROCESS=$!
+wait_process_startup ${RSYSLOG_DYNNAME}${testsrv} ${RSYSLOG_DYNNAME}${testsrv}.started
+echo background mmkubernetes_test_server.py process id is $BGPROCESS
+
+cat > ${RSYSLOG_DYNNAME}.spool/pod-error1.log <<EOF
+{"log":"not in right format","stream":"stdout","time":"2018-04-06T17:26:34.492083106Z","testid":1}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-error2.log <<EOF
+{"message":"not in right format","CONTAINER_NAME":"not in right format","CONTAINER_ID_FULL":"id3","testid":2}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-name1_namespace-name1_container-name1-id1.log <<EOF
+{"log":"{\"type\":\"response\",\"@timestamp\":\"2018-04-06T17:26:34Z\",\"tags\":[],\"pid\":75,\"method\":\"head\",\"statusCode\":200,\"req\":{\"url\":\"/\",\"method\":\"head\",\"headers\":{\"user-agent\":\"curl/7.29.0\",\"host\":\"localhost:5601\",\"accept\":\"*/*\"},\"remoteAddress\":\"127.0.0.1\",\"userAgent\":\"127.0.0.1\"},\"res\":{\"statusCode\":200,\"responseTime\":1,\"contentLength\":9},\"message\":\"HEAD1 / 200 1ms - 9.0B\"}\n","stream":"stdout","time":"2018-04-06T17:26:34.492083106Z","testid":3}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-name2.container-hash2_namespace-name2_container-name2-id2.log <<EOF
+{"log":"{\"type\":\"response\",\"@timestamp\":\"2018-04-06T17:26:34Z\",\"tags\":[],\"pid\":75,\"method\":\"head\",\"statusCode\":200,\"req\":{\"url\":\"/\",\"method\":\"head\",\"headers\":{\"user-agent\":\"curl/7.29.0\",\"host\":\"localhost:5601\",\"accept\":\"*/*\"},\"remoteAddress\":\"127.0.0.1\",\"userAgent\":\"127.0.0.1\"},\"res\":{\"statusCode\":200,\"responseTime\":1,\"contentLength\":9},\"message\":\"HEAD2 / 200 1ms - 9.0B\"}\n","stream":"stdout","time":"2018-04-06T17:26:34.492083106Z","testid":4}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-name3.log <<EOF
+{"message":"a message from container 3","CONTAINER_NAME":"some-prefix_container-name3.container-hash3_pod-name3_namespace-name3_unused3_unused33","CONTAINER_ID_FULL":"id3","testid":5}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-name4.log <<EOF
+{"message":"a message from container 4","CONTAINER_NAME":"some-prefix_container-name4_pod-name4_namespace-name4_unused4_unused44","CONTAINER_ID_FULL":"id4","testid":6}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-name5.log <<EOF
+{"message":"a message from container 5","CONTAINER_NAME":"some-prefix_container-name5_pod-name5.with.dot.in.pod.name_namespace-name5_unused5_unused55","CONTAINER_ID_FULL":"id5","testid":7}
+EOF
+
+if [ "${USE_VALGRIND:-false}" == "true" ] ; then
+ export EXTRA_VALGRIND_SUPPRESSIONS="--suppressions=$srcdir/mmkubernetes.supp"
+ startup_vg
+else
+ startup
+fi
+# wait for the first batch of tests to complete
+wait_queueempty
+
+cat > ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <<EOF
+{"message":"this record should have no namespace metadata","CONTAINER_NAME":"some-prefix_container-name-6_pod-name-6_namespace-name-6-not-found_unused6_unused66","CONTAINER_ID_FULL":"id6","testid":8}
+{"message":"this record should have no pod metadata","CONTAINER_NAME":"some-prefix_container-name-7_pod-name-7-not-found_namespace-name-7_unused7_unused77","CONTAINER_ID_FULL":"id7","testid":9}
+{"message":"this record should have no namespace or pod metadata and retry","CONTAINER_NAME":"some-prefix_container-name-8_pod-name-8_namespace-name-8-busy_unused8_unused88","CONTAINER_ID_FULL":"id8","testid":10}
+EOF
+
+wait_queueempty
+sleep 5 # greater than busyretryinterval
+
+cat >> ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <<EOF
+{"message":"this record should have namespace and pod metadata after retry","CONTAINER_NAME":"some-prefix_container-name-8_pod-name-8_namespace-name-8-busy_unused8_unused88","CONTAINER_ID_FULL":"id8","testid":11}
+{"message":"this record should have no pod metadata and retry","CONTAINER_NAME":"some-prefix_container-name-9_pod-name-9-busy_namespace-name-9_unused9_unused99","CONTAINER_ID_FULL":"id9","testid":12}
+EOF
+
+wait_queueempty
+sleep 5 # greater than busyretryinterval
+
+cat >> ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <<EOF
+{"message":"this record should have pod metadata after retry","CONTAINER_NAME":"some-prefix_container-name-9_pod-name-9-busy_namespace-name-9_unused9_unused99","CONTAINER_ID_FULL":"id9","testid":13}
+{"message":"this record should process normally","CONTAINER_NAME":"some-prefix_container-name-10_pod-name-10_namespace-name-10_unused10_unused100","CONTAINER_ID_FULL":"id10","testid":14}
+EOF
+
+wait_queueempty
+sleep 5 # greater than busyretryinterval
+
+cat >> ${RSYSLOG_DYNNAME}.spool/pod-test-error.log <<EOF
+{"message":"this record should have no pod metadata","CONTAINER_NAME":"some-prefix_container-name-11_pod-name-11-error_namespace-name-11_unused11_unused111","CONTAINER_ID_FULL":"id11","testid":15}
+{"message":"this record should process normally","CONTAINER_NAME":"some-prefix_container-name-12_pod-name-12_namespace-name-12_unused12_unused112","CONTAINER_ID_FULL":"id12","testid":16}
+EOF
+
+
+shutdown_when_empty
+if [ "${USE_VALGRIND:-false}" == "true" ] ; then
+ wait_shutdown_vg
+ check_exit_vg
+else
+ wait_shutdown
+fi
+kill $BGPROCESS
+wait_pid_termination ${RSYSLOG_DYNNAME}${testsrv}.pid
+
+rc=0
+# for each record in mmkubernetes-basic.out.json, see if the matching
+# record is found in $RSYSLOG_OUT_LOG
+$PYTHON -c 'import sys,json
+k8s_srv_port = sys.argv[3]
+expected = {}
+for hsh in json.load(open(sys.argv[1])):
+ if "testid" in hsh:
+ if "kubernetes" in hsh and "master_url" in hsh["kubernetes"]:
+ hsh["kubernetes"]["master_url"] = hsh["kubernetes"]["master_url"].format(k8s_srv_port=k8s_srv_port)
+ expected[hsh["testid"]] = hsh
+rc = 0
+actual = {}
+for line in open(sys.argv[2]):
+ hsh = json.loads(line)
+ if "testid" in hsh:
+ actual[hsh["testid"]] = hsh
+for testid,hsh in expected.items():
+ if not testid in actual:
+ print("Error: record for testid {0} not found in output".format(testid))
+ rc = 1
+ else:
+ for kk,vv in hsh.items():
+ if not kk in actual[testid]:
+ print("Error: key {0} in record for testid {1} not found in output".format(kk, testid))
+ rc = 1
+ elif not vv == actual[testid][kk]:
+ print("Error: value {0} for key {1} in record for testid {2} does not match the expected value {3}".format(str(actual[testid][kk]), kk, testid, str(vv)))
+ rc = 1
+sys.exit(rc)
+' $srcdir/mmkubernetes-basic.out.json $RSYSLOG_OUT_LOG $k8s_srv_port || rc=$?
+grep -q 'mmkubernetes: Not Found: the resource does not exist at url .*/namespaces\\\/namespace-name-6-not-found' $RSYSLOG_OUT_LOG || { echo fail1; rc=1; }
+grep -q 'mmkubernetes: Not Found: the resource does not exist at url .*/pods\\\/pod-name-7-not-found' $RSYSLOG_OUT_LOG || { echo fail2; rc=1; }
+grep -q 'mmkubernetes: Too Many Requests: the server is too heavily loaded to provide the data for the requested url .*/namespaces\\\/namespace-name-8-busy' $RSYSLOG_OUT_LOG || { echo fail3; rc=1; }
+grep -q 'mmkubernetes: Too Many Requests: the server is too heavily loaded to provide the data for the requested url .*/pods\\\/pod-name-9-busy' $RSYSLOG_OUT_LOG || { echo fail4; rc=1; }
+
+if [ -f ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log ] ; then
+ $PYTHON <${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log -c '
+import sys,json
+k8s_srv_port = sys.argv[1]
+expected = {"name": "mmkubernetes(http://localhost:{0})".format(k8s_srv_port),
+ "origin": "mmkubernetes", "recordseen": 14, "namespacemetadatasuccess": 11,
+ "namespacemetadatanotfound": 1, "namespacemetadatabusy": 1, "namespacemetadataerror": 0,
+ "podmetadatasuccess": 10, "podmetadatanotfound": 1, "podmetadatabusy": 2, "podmetadataerror": 1,
+ "namespacecachenumentries": 12, "podcachenumentries": 12, "namespacecachehits": 1,
+ "podcachehits": 0, "namespacecachemisses": 13, "podcachemisses": 14 }
+actual = {}
+for line in sys.stdin:
+ jstart = line.find("{")
+ if jstart >= 0:
+ hsh = json.loads(line[jstart:])
+ if hsh["origin"] == "mmkubernetes":
+ actual = hsh
+assert(expected == actual)
+' $k8s_srv_port || { rc=$?; echo error: expected stats not found in ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log; }
+else
+ echo error: stats file ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log not found
+ rc=1
+fi
+
+if [ ${rc:-0} -ne 0 ]; then
+ echo
+ echo "FAIL: expected data not found. $RSYSLOG_OUT_LOG is:"
+ cat ${RSYSLOG_DYNNAME}.spool/mmk8s_srv.log
+ cat $RSYSLOG_OUT_LOG
+ cat ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/mmkubernetes-basic.out.json b/tests/mmkubernetes-basic.out.json
new file mode 100644
index 0000000..c518003
--- /dev/null
+++ b/tests/mmkubernetes-basic.out.json
@@ -0,0 +1,376 @@
+[{
+ "log": "not in right format",
+ "testid": 1
+},
+{
+ "message": "not in right format",
+ "testid": 2
+},
+{
+ "kubernetes": {
+ "namespace_id": "namespace-name2-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name2-id",
+ "labels": {
+ "custom_label": "pod-name2-label-value",
+ "deploymentconfig": "pod-name2-dc",
+ "component": "pod-name2-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name2-deployment"
+ },
+ "pod_name": "pod-name2",
+ "namespace_name": "namespace-name2",
+ "container_name": "container-name2",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id2"
+ },
+ "testid": 4
+},
+{
+ "message": "a message from container 4",
+ "CONTAINER_NAME": "some-prefix_container-name4_pod-name4_namespace-name4_unused4_unused44",
+ "CONTAINER_ID_FULL": "id4",
+ "kubernetes": {
+ "namespace_id": "namespace-name4-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name4-id",
+ "labels": {
+ "custom_label": "pod-name4-label-value",
+ "deploymentconfig": "pod-name4-dc",
+ "component": "pod-name4-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name4-deployment"
+ },
+ "pod_name": "pod-name4",
+ "namespace_name": "namespace-name4",
+ "container_name": "container-name4",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id4"
+ },
+ "testid": 6
+},
+{
+ "kubernetes": {
+ "namespace_id": "namespace-name1-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name1-id",
+ "labels": {
+ "custom_label": "pod-name1-label-value",
+ "deploymentconfig": "pod-name1-dc",
+ "component": "pod-name1-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name1-deployment"
+ },
+ "pod_name": "pod-name1",
+ "namespace_name": "namespace-name1",
+ "container_name": "container-name1",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id1"
+ },
+ "testid": 3
+},
+{
+ "message": "a message from container 3",
+ "CONTAINER_NAME": "some-prefix_container-name3.container-hash3_pod-name3_namespace-name3_unused3_unused33",
+ "CONTAINER_ID_FULL": "id3",
+ "kubernetes": {
+ "namespace_id": "namespace-name3-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name3-id",
+ "labels": {
+ "custom_label": "pod-name3-label-value",
+ "deploymentconfig": "pod-name3-dc",
+ "component": "pod-name3-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name3-deployment"
+ },
+ "pod_name": "pod-name3",
+ "namespace_name": "namespace-name3",
+ "container_name": "container-name3",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id3"
+ },
+ "testid": 5
+},
+{
+ "message": "a message from container 5",
+ "CONTAINER_NAME": "some-prefix_container-name5_pod-name5.with.dot.in.pod.name_namespace-name5_unused5_unused55",
+ "CONTAINER_ID_FULL": "id5",
+ "kubernetes": {
+ "namespace_id": "namespace-name5-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name5.with.dot.in.pod.name-id",
+ "labels": {
+ "custom_label": "pod-name5.with.dot.in.pod.name-label-value",
+ "deploymentconfig": "pod-name5.with.dot.in.pod.name-dc",
+ "component": "pod-name5.with.dot.in.pod.name-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name5.with.dot.in.pod.name-deployment"
+ },
+ "pod_name": "pod-name5.with.dot.in.pod.name",
+ "namespace_name": "namespace-name5",
+ "container_name": "container-name5",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id5"
+ },
+ "testid": 7
+},
+{
+ "message":"this record should have no namespace metadata",
+ "CONTAINER_NAME":"some-prefix_container-name-6_pod-name-6_namespace-name-6-not-found_unused6_unused66",
+ "CONTAINER_ID_FULL":"id6",
+ "kubernetes": {
+ "pod_id":"pod-name-6-id",
+ "labels": {
+ "custom_label":"pod-name-6-label-value",
+ "deploymentconfig":"pod-name-6-dc",
+ "component":"pod-name-6-component",
+ "label_with_empty_value":"",
+ "deployment":"pod-name-6-deployment"
+ },
+ "pod_name":"pod-name-6",
+ "namespace_name":"namespace-name-6-not-found",
+ "container_name":"container-name-6",
+ "master_url":"http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id":"id6"
+ },
+ "testid": 8
+},
+{
+ "message": "this record should have no pod metadata",
+ "CONTAINER_NAME": "some-prefix_container-name-7_pod-name-7-not-found_namespace-name-7_unused7_unused77",
+ "CONTAINER_ID_FULL": "id7",
+ "kubernetes": {
+ "namespace_id": "namespace-name-7-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_name": "pod-name-7-not-found",
+ "namespace_name": "namespace-name-7",
+ "container_name": "container-name-7",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id7"
+ },
+ "testid": 9
+},
+{
+ "message": "this record should have no namespace or pod metadata and retry",
+ "CONTAINER_NAME": "some-prefix_container-name-8_pod-name-8_namespace-name-8-busy_unused8_unused88",
+ "CONTAINER_ID_FULL": "id8",
+ "kubernetes": {
+ "pod_name": "pod-name-8",
+ "namespace_name": "namespace-name-8-busy",
+ "container_name": "container-name-8",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id8"
+ },
+ "testid": 10
+},
+{
+ "message": "this record should have namespace and pod metadata after retry",
+ "CONTAINER_NAME": "some-prefix_container-name-8_pod-name-8_namespace-name-8-busy_unused8_unused88",
+ "CONTAINER_ID_FULL": "id8",
+ "kubernetes": {
+ "namespace_id": "namespace-name-8-busy-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name-8-id",
+ "labels": {
+ "custom_label": "pod-name-8-label-value",
+ "deploymentconfig": "pod-name-8-dc",
+ "component": "pod-name-8-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name-8-deployment"
+ },
+ "pod_name": "pod-name-8",
+ "namespace_name": "namespace-name-8-busy",
+ "container_name": "container-name-8",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id8"
+ },
+ "testid": 11
+},
+{
+ "message": "this record should have no pod metadata and retry",
+ "CONTAINER_NAME": "some-prefix_container-name-9_pod-name-9-busy_namespace-name-9_unused9_unused99",
+ "CONTAINER_ID_FULL": "id9",
+ "kubernetes": {
+ "namespace_id": "namespace-name-9-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_name": "pod-name-9-busy",
+ "namespace_name": "namespace-name-9",
+ "container_name": "container-name-9",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id9"
+ },
+ "testid": 12
+},
+{
+ "message": "this record should have pod metadata after retry",
+ "CONTAINER_NAME": "some-prefix_container-name-9_pod-name-9-busy_namespace-name-9_unused9_unused99",
+ "CONTAINER_ID_FULL": "id9",
+ "kubernetes": {
+ "namespace_id": "namespace-name-9-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name-9-busy-id",
+ "labels": {
+ "custom_label": "pod-name-9-busy-label-value",
+ "deploymentconfig": "pod-name-9-busy-dc",
+ "component": "pod-name-9-busy-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name-9-busy-deployment"
+ },
+ "pod_name": "pod-name-9-busy",
+ "namespace_name": "namespace-name-9",
+ "container_name": "container-name-9",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id9"
+ },
+ "testid": 13
+},
+{
+ "message": "this record should process normally",
+ "CONTAINER_NAME": "some-prefix_container-name-10_pod-name-10_namespace-name-10_unused10_unused100",
+ "CONTAINER_ID_FULL": "id10",
+ "kubernetes": {
+ "namespace_id": "namespace-name-10-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name-10-id",
+ "labels": {
+ "custom_label": "pod-name-10-label-value",
+ "deploymentconfig": "pod-name-10-dc",
+ "component": "pod-name-10-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name-10-deployment"
+ },
+ "pod_name": "pod-name-10",
+ "namespace_name": "namespace-name-10",
+ "container_name": "container-name-10",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id10"
+ },
+ "testid": 14
+},
+{
+ "message": "this record should have no pod metadata",
+ "CONTAINER_NAME": "some-prefix_container-name-11_pod-name-11-error_namespace-name-11_unused11_unused111",
+ "CONTAINER_ID_FULL": "id11",
+ "kubernetes": {
+ "namespace_id": "namespace-name-11-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_name": "pod-name-11-error",
+ "namespace_name": "namespace-name-11",
+ "container_name": "container-name-11",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id11"
+ },
+ "testid": 15
+},
+{
+ "message": "this record should process normally",
+ "CONTAINER_NAME": "some-prefix_container-name-12_pod-name-12_namespace-name-12_unused12_unused112",
+ "CONTAINER_ID_FULL": "id12",
+ "kubernetes": {
+ "namespace_id": "namespace-name-12-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name-12-id",
+ "labels": {
+ "custom_label": "pod-name-12-label-value",
+ "deploymentconfig": "pod-name-12-dc",
+ "component": "pod-name-12-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name-12-deployment"
+ },
+ "pod_name": "pod-name-12",
+ "namespace_name": "namespace-name-12",
+ "container_name": "container-name-12",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id12"
+ },
+ "testid": 16
+}]
diff --git a/tests/mmkubernetes-basic.sh b/tests/mmkubernetes-basic.sh
new file mode 100755
index 0000000..90f43c4
--- /dev/null
+++ b/tests/mmkubernetes-basic.sh
@@ -0,0 +1,187 @@
+#!/bin/bash
+# added 2018-04-06 by richm, released under ASL 2.0
+#
+# Note: on buildbot VMs (where there is no environment cleanup), the
+# kubernetes test server may be kept running if the script aborts or
+# is aborted (buildbot master failure!) for some reason. As such we
+# execute it under "timeout" control, which ensure it always is
+# terminated. It's not a 100% great method, but hopefully does the
+# trick. -- rgerhards, 2018-07-21
+#export RSYSLOG_DEBUG="debug"
+USE_VALGRIND=false
+. ${srcdir:=.}/diag.sh init
+check_command_available timeout
+pwd=$( pwd )
+k8s_srv_port=$( get_free_port )
+generate_conf
+add_conf '
+global(workDirectory="'$RSYSLOG_DYNNAME.spool'")
+module(load="../plugins/impstats/.libs/impstats" interval="1"
+ log.file="'"$RSYSLOG_DYNNAME.spool"'/mmkubernetes-stats.log" log.syslog="off" format="cee")
+module(load="../plugins/imfile/.libs/imfile")
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../contrib/mmkubernetes/.libs/mmkubernetes")
+
+template(name="mmk8s_template" type="list") {
+ property(name="$!all-json-plain")
+ constant(value="\n")
+}
+
+input(type="imfile" file="'$RSYSLOG_DYNNAME.spool'/pod-*.log" tag="kubernetes" addmetadata="on")
+action(type="mmjsonparse" cookie="")
+action(type="mmkubernetes" busyretryinterval="1" token="dummy" kubernetesurl="http://localhost:'$k8s_srv_port'"
+ filenamerules=["rule=:'$pwd/$RSYSLOG_DYNNAME.spool'/%pod_name:char-to:.%.%container_hash:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log",
+ "rule=:'$pwd/$RSYSLOG_DYNNAME.spool'/%pod_name:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log"]
+)
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="mmk8s_template")
+'
+
+testsrv=mmk8s-test-server
+echo starting kubernetes \"emulator\"
+timeout 2m $PYTHON -u $srcdir/mmkubernetes_test_server.py $k8s_srv_port ${RSYSLOG_DYNNAME}${testsrv}.pid ${RSYSLOG_DYNNAME}${testsrv}.started > ${RSYSLOG_DYNNAME}.spool/mmk8s_srv.log 2>&1 &
+BGPROCESS=$!
+wait_process_startup ${RSYSLOG_DYNNAME}${testsrv} ${RSYSLOG_DYNNAME}${testsrv}.started
+echo background mmkubernetes_test_server.py process id is $BGPROCESS
+
+cat > ${RSYSLOG_DYNNAME}.spool/pod-error1.log <<EOF
+{"log":"not in right format","stream":"stdout","time":"2018-04-06T17:26:34.492083106Z","testid":1}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-error2.log <<EOF
+{"message":"not in right format","CONTAINER_NAME":"not in right format","CONTAINER_ID_FULL":"id3","testid":2}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-name1_namespace-name1_container-name1-id1.log <<EOF
+{"log":"{\"type\":\"response\",\"@timestamp\":\"2018-04-06T17:26:34Z\",\"tags\":[],\"pid\":75,\"method\":\"head\",\"statusCode\":200,\"req\":{\"url\":\"/\",\"method\":\"head\",\"headers\":{\"user-agent\":\"curl/7.29.0\",\"host\":\"localhost:5601\",\"accept\":\"*/*\"},\"remoteAddress\":\"127.0.0.1\",\"userAgent\":\"127.0.0.1\"},\"res\":{\"statusCode\":200,\"responseTime\":1,\"contentLength\":9},\"message\":\"HEAD1 / 200 1ms - 9.0B\"}\n","stream":"stdout","time":"2018-04-06T17:26:34.492083106Z","testid":3}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-name2.container-hash2_namespace-name2_container-name2-id2.log <<EOF
+{"log":"{\"type\":\"response\",\"@timestamp\":\"2018-04-06T17:26:34Z\",\"tags\":[],\"pid\":75,\"method\":\"head\",\"statusCode\":200,\"req\":{\"url\":\"/\",\"method\":\"head\",\"headers\":{\"user-agent\":\"curl/7.29.0\",\"host\":\"localhost:5601\",\"accept\":\"*/*\"},\"remoteAddress\":\"127.0.0.1\",\"userAgent\":\"127.0.0.1\"},\"res\":{\"statusCode\":200,\"responseTime\":1,\"contentLength\":9},\"message\":\"HEAD2 / 200 1ms - 9.0B\"}\n","stream":"stdout","time":"2018-04-06T17:26:34.492083106Z","testid":4}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-name3.log <<EOF
+{"message":"a message from container 3","CONTAINER_NAME":"some-prefix_container-name3.container-hash3_pod-name3_namespace-name3_unused3_unused33","CONTAINER_ID_FULL":"id3","testid":5}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-name4.log <<EOF
+{"message":"a message from container 4","CONTAINER_NAME":"some-prefix_container-name4_pod-name4_namespace-name4_unused4_unused44","CONTAINER_ID_FULL":"id4","testid":6}
+EOF
+cat > ${RSYSLOG_DYNNAME}.spool/pod-name5.log <<EOF
+{"message":"a message from container 5","CONTAINER_NAME":"some-prefix_container-name5_pod-name5.with.dot.in.pod.name_namespace-name5_unused5_unused55","CONTAINER_ID_FULL":"id5","testid":7}
+EOF
+
+if [ "${USE_VALGRIND:-false}" == "true" ] ; then
+ export EXTRA_VALGRIND_SUPPRESSIONS="--suppressions=$srcdir/mmkubernetes.supp"
+ startup_vg
+else
+ startup
+fi
+# wait for the first batch of tests to complete
+wait_queueempty
+
+cat > ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <<EOF
+{"message":"this record should have no namespace metadata","CONTAINER_NAME":"some-prefix_container-name-6_pod-name-6_namespace-name-6-not-found_unused6_unused66","CONTAINER_ID_FULL":"id6","testid":8}
+{"message":"this record should have no pod metadata","CONTAINER_NAME":"some-prefix_container-name-7_pod-name-7-not-found_namespace-name-7_unused7_unused77","CONTAINER_ID_FULL":"id7","testid":9}
+{"message":"this record should have no namespace or pod metadata and retry","CONTAINER_NAME":"some-prefix_container-name-8_pod-name-8_namespace-name-8-busy_unused8_unused88","CONTAINER_ID_FULL":"id8","testid":10}
+EOF
+
+wait_queueempty
+sleep 5 # greater than busyretryinterval
+
+cat >> ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <<EOF
+{"message":"this record should have namespace and pod metadata after retry","CONTAINER_NAME":"some-prefix_container-name-8_pod-name-8_namespace-name-8-busy_unused8_unused88","CONTAINER_ID_FULL":"id8","testid":11}
+{"message":"this record should have no pod metadata and retry","CONTAINER_NAME":"some-prefix_container-name-9_pod-name-9-busy_namespace-name-9_unused9_unused99","CONTAINER_ID_FULL":"id9","testid":12}
+EOF
+
+wait_queueempty
+sleep 5 # greater than busyretryinterval
+
+cat >> ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <<EOF
+{"message":"this record should have pod metadata after retry","CONTAINER_NAME":"some-prefix_container-name-9_pod-name-9-busy_namespace-name-9_unused9_unused99","CONTAINER_ID_FULL":"id9","testid":13}
+{"message":"this record should process normally","CONTAINER_NAME":"some-prefix_container-name-10_pod-name-10_namespace-name-10_unused10_unused100","CONTAINER_ID_FULL":"id10","testid":14}
+EOF
+
+wait_queueempty
+sleep 5 # greater than busyretryinterval
+
+cat >> ${RSYSLOG_DYNNAME}.spool/pod-test-error.log <<EOF
+{"message":"this record should have no pod metadata","CONTAINER_NAME":"some-prefix_container-name-11_pod-name-11-error_namespace-name-11_unused11_unused111","CONTAINER_ID_FULL":"id11","testid":15}
+{"message":"this record should process normally","CONTAINER_NAME":"some-prefix_container-name-12_pod-name-12_namespace-name-12_unused12_unused112","CONTAINER_ID_FULL":"id12","testid":16}
+EOF
+
+
+shutdown_when_empty
+if [ "${USE_VALGRIND:-false}" == "true" ] ; then
+ wait_shutdown_vg
+ check_exit_vg
+else
+ wait_shutdown
+fi
+kill $BGPROCESS
+wait_pid_termination ${RSYSLOG_DYNNAME}${testsrv}.pid
+
+rc=0
+# for each record in mmkubernetes-basic.out.json, see if the matching
+# record is found in $RSYSLOG_OUT_LOG
+$PYTHON -c 'import sys,json
+k8s_srv_port = sys.argv[3]
+expected = {}
+for hsh in json.load(open(sys.argv[1])):
+ if "testid" in hsh:
+ if "kubernetes" in hsh and "master_url" in hsh["kubernetes"]:
+ hsh["kubernetes"]["master_url"] = hsh["kubernetes"]["master_url"].format(k8s_srv_port=k8s_srv_port)
+ expected[hsh["testid"]] = hsh
+rc = 0
+actual = {}
+for line in open(sys.argv[2]):
+ hsh = json.loads(line)
+ if "testid" in hsh:
+ actual[hsh["testid"]] = hsh
+for testid,hsh in expected.items():
+ if not testid in actual:
+ print("Error: record for testid {0} not found in output".format(testid))
+ rc = 1
+ else:
+ for kk,vv in hsh.items():
+ if not kk in actual[testid]:
+ print("Error: key {0} in record for testid {1} not found in output".format(kk, testid))
+ rc = 1
+ elif not vv == actual[testid][kk]:
+ print("Error: value {0} for key {1} in record for testid {2} does not match the expected value {3}".format(str(actual[testid][kk]), kk, testid, str(vv)))
+ rc = 1
+sys.exit(rc)
+' $srcdir/mmkubernetes-basic.out.json $RSYSLOG_OUT_LOG $k8s_srv_port || rc=$?
+grep -q 'mmkubernetes: Not Found: the resource does not exist at url .*/namespaces\\\/namespace-name-6-not-found' $RSYSLOG_OUT_LOG || { echo fail1; rc=1; }
+grep -q 'mmkubernetes: Not Found: the resource does not exist at url .*/pods\\\/pod-name-7-not-found' $RSYSLOG_OUT_LOG || { echo fail2; rc=1; }
+grep -q 'mmkubernetes: Too Many Requests: the server is too heavily loaded to provide the data for the requested url .*/namespaces\\\/namespace-name-8-busy' $RSYSLOG_OUT_LOG || { echo fail3; rc=1; }
+grep -q 'mmkubernetes: Too Many Requests: the server is too heavily loaded to provide the data for the requested url .*/pods\\\/pod-name-9-busy' $RSYSLOG_OUT_LOG || { echo fail4; rc=1; }
+
+if [ -f ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log ] ; then
+ $PYTHON <${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log -c '
+import sys,json
+k8s_srv_port = sys.argv[1]
+expected = {"name": "mmkubernetes(http://localhost:{0})".format(k8s_srv_port),
+ "origin": "mmkubernetes", "recordseen": 14, "namespacemetadatasuccess": 11,
+ "namespacemetadatanotfound": 1, "namespacemetadatabusy": 1, "namespacemetadataerror": 0,
+ "podmetadatasuccess": 10, "podmetadatanotfound": 1, "podmetadatabusy": 2, "podmetadataerror": 1,
+ "namespacecachenumentries": 12, "podcachenumentries": 12, "namespacecachehits": 1,
+ "podcachehits": 0, "namespacecachemisses": 13, "podcachemisses": 14 }
+actual = {}
+for line in sys.stdin:
+ jstart = line.find("{")
+ if jstart >= 0:
+ hsh = json.loads(line[jstart:])
+ if hsh["origin"] == "mmkubernetes":
+ actual = hsh
+assert(expected == actual)
+' $k8s_srv_port || { rc=$?; echo error: expected stats not found in ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log; }
+else
+ echo error: stats file ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log not found
+ rc=1
+fi
+
+if [ ${rc:-0} -ne 0 ]; then
+ echo
+ echo "FAIL: expected data not found. $RSYSLOG_OUT_LOG is:"
+ cat ${RSYSLOG_DYNNAME}.spool/mmk8s_srv.log
+ cat $RSYSLOG_OUT_LOG
+ cat ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/mmkubernetes-cache-expire-vg.sh b/tests/mmkubernetes-cache-expire-vg.sh
new file mode 100755
index 0000000..e19aeb3
--- /dev/null
+++ b/tests/mmkubernetes-cache-expire-vg.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# added 2018-04-06 by richm, released under ASL 2.0
+#
+# Note: on buildbot VMs (where there is no environment cleanup), the
+# kubernetes test server may be kept running if the script aborts or
+# is aborted (buildbot master failure!) for some reason. As such we
+# execute it under "timeout" control, which ensure it always is
+# terminated. It's not a 100% great method, but hopefully does the
+# trick. -- rgerhards, 2018-07-21
+#export RSYSLOG_DEBUG="debug"
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/mmkubernetes-cache-expire.sh
diff --git a/tests/mmkubernetes-cache-expire.out.expected b/tests/mmkubernetes-cache-expire.out.expected
new file mode 100644
index 0000000..b2dc92d
--- /dev/null
+++ b/tests/mmkubernetes-cache-expire.out.expected
@@ -0,0 +1,109 @@
+[{
+ "kubernetes": {
+ "namespace_id": "namespace-name1-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name1-id",
+ "labels": {
+ "custom_label": "pod-name1-label-value",
+ "deploymentconfig": "pod-name1-dc",
+ "component": "pod-name1-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name1-deployment"
+ },
+ "pod_name": "pod-name1",
+ "namespace_name": "namespace-name1",
+ "container_name": "container-name1",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id1"
+ },
+ "testid": 1,
+ "message": "msg1"
+},{
+ "kubernetes": {
+ "namespace_id": "namespace-name1-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name1-id",
+ "labels": {
+ "custom_label": "pod-name1-label-value",
+ "deploymentconfig": "pod-name1-dc",
+ "component": "pod-name1-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name1-deployment"
+ },
+ "pod_name": "pod-name1",
+ "namespace_name": "namespace-name1",
+ "container_name": "container-name1",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id1"
+ },
+ "testid": 2,
+ "message": "msg2"
+},{
+ "kubernetes": {
+ "namespace_id": "namespace-name1-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name1-id",
+ "labels": {
+ "custom_label": "pod-name1-label-value",
+ "deploymentconfig": "pod-name1-dc",
+ "component": "pod-name1-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name1-deployment"
+ },
+ "pod_name": "pod-name1",
+ "namespace_name": "namespace-name1",
+ "container_name": "container-name1",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id1"
+ },
+ "testid": 3,
+ "message": "msg3"
+},{
+ "kubernetes": {
+ "namespace_id": "namespace-name1-id",
+ "namespace_labels": {
+ "label_1_key": "label 1 value",
+ "label_with_empty_value": "",
+ "label_2_key": "label 2 value"
+ },
+ "creation_timestamp": "2018-04-09T21:56:39Z",
+ "pod_id": "pod-name1-id",
+ "labels": {
+ "custom_label": "pod-name1-label-value",
+ "deploymentconfig": "pod-name1-dc",
+ "component": "pod-name1-component",
+ "label_with_empty_value": "",
+ "deployment": "pod-name1-deployment"
+ },
+ "pod_name": "pod-name1",
+ "namespace_name": "namespace-name1",
+ "container_name": "container-name1",
+ "master_url": "http://localhost:{k8s_srv_port}"
+ },
+ "docker": {
+ "container_id": "id1"
+ },
+ "testid": 4,
+ "message": "msg4"
+}]
diff --git a/tests/mmkubernetes-cache-expire.sh b/tests/mmkubernetes-cache-expire.sh
new file mode 100755
index 0000000..fdb7226
--- /dev/null
+++ b/tests/mmkubernetes-cache-expire.sh
@@ -0,0 +1,167 @@
+#!/bin/bash
+# added 2018-04-06 by richm, released under ASL 2.0
+#
+# Note: on buildbot VMs (where there is no environment cleanup), the
+# kubernetes test server may be kept running if the script aborts or
+# is aborted (buildbot master failure!) for some reason. As such we
+# execute it under "timeout" control, which ensure it always is
+# terminated. It's not a 100% great method, but hopefully does the
+# trick. -- rgerhards, 2018-07-21
+. ${srcdir:=.}/diag.sh init
+check_command_available timeout
+pwd=$( pwd )
+k8s_srv_port=$( get_free_port )
+generate_conf
+cachettl=10
+add_conf '
+global(workDirectory="'$RSYSLOG_DYNNAME.spool'")
+module(load="../plugins/impstats/.libs/impstats" interval="1"
+ log.file="'"$RSYSLOG_DYNNAME.spool"'/mmkubernetes-stats.log" log.syslog="off" format="cee")
+module(load="../plugins/imfile/.libs/imfile")
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../contrib/mmkubernetes/.libs/mmkubernetes")
+
+template(name="mmk8s_template" type="list") {
+ property(name="$!all-json-plain")
+ constant(value="\n")
+}
+
+input(type="imfile" file="'$RSYSLOG_DYNNAME.spool'/pod-*.log" tag="kubernetes" addmetadata="on")
+action(type="mmjsonparse" cookie="")
+action(type="mmkubernetes" token="dummy" kubernetesurl="http://localhost:'$k8s_srv_port'"
+ cacheexpireinterval="1" cacheentryttl="'$cachettl'"
+ filenamerules=["rule=:'$pwd/$RSYSLOG_DYNNAME.spool'/%pod_name:char-to:.%.%container_hash:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log",
+ "rule=:'$pwd/$RSYSLOG_DYNNAME.spool'/%pod_name:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log"]
+)
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="mmk8s_template")
+'
+
+testsrv=mmk8s-test-server
+echo starting kubernetes \"emulator\"
+timeout 2m $PYTHON -u $srcdir/mmkubernetes_test_server.py $k8s_srv_port ${RSYSLOG_DYNNAME}${testsrv}.pid ${RSYSLOG_DYNNAME}${testsrv}.started > ${RSYSLOG_DYNNAME}.spool/mmk8s_srv.log 2>&1 &
+BGPROCESS=$!
+wait_process_startup ${RSYSLOG_DYNNAME}${testsrv} ${RSYSLOG_DYNNAME}${testsrv}.started
+echo background mmkubernetes_test_server.py process id is $BGPROCESS
+
+if [ "x${USE_VALGRIND:-NO}" == "xYES" ] ; then
+ export EXTRA_VALGRIND_SUPPRESSIONS="--suppressions=$srcdir/mmkubernetes.supp"
+ startup_vg
+else
+ startup
+ if [ -n "${USE_GDB:-}" ] ; then
+ echo attach gdb here
+ sleep 54321 || :
+ fi
+fi
+
+# add 3 logs - then wait $cachettl - the first log should prime the cache - the next two should be pulled from the cache
+cat > ${RSYSLOG_DYNNAME}.spool/pod-name.log <<EOF
+{"message":"msg1","CONTAINER_NAME":"some-prefix_container-name1_pod-name1_namespace-name1_unused1_unused11","CONTAINER_ID_FULL":"id1","testid":1}
+EOF
+sleep 2
+cat >> ${RSYSLOG_DYNNAME}.spool/pod-name.log <<EOF
+{"message":"msg2","CONTAINER_NAME":"some-prefix_container-name1_pod-name1_namespace-name1_unused1_unused11","CONTAINER_ID_FULL":"id1","testid":2}
+EOF
+sleep 2
+cat >> ${RSYSLOG_DYNNAME}.spool/pod-name.log <<EOF
+{"message":"msg3","CONTAINER_NAME":"some-prefix_container-name1_pod-name1_namespace-name1_unused1_unused11","CONTAINER_ID_FULL":"id1","testid":3}
+EOF
+sleep $cachettl
+# we should see
+# - namespacecachenumentries and podcachenumentries go from 0 to 1 then back to 0
+# - namespacecachehits and podcachehits go from 0 to 2
+# - namespacecachemisses and podcachemisses go from 0 to 1
+# add another record - should not be cached - should have expired
+cat >> ${RSYSLOG_DYNNAME}.spool/pod-name.log <<EOF
+{"message":"msg4","CONTAINER_NAME":"some-prefix_container-name1_pod-name1_namespace-name1_unused1_unused11","CONTAINER_ID_FULL":"id1","testid":4}
+EOF
+# we should see
+# - namespacecachenumentries and podcachenumentries back to 1
+# - namespacecachehits and podcachehits did not increase
+# - namespacecachemisses and podcachemisses increases
+
+# wait for the first batch of tests to complete
+wait_queueempty
+
+shutdown_when_empty
+if [ "x${USE_VALGRIND:-NO}" == "xYES" ] ; then
+ wait_shutdown_vg
+ check_exit_vg
+else
+ wait_shutdown
+fi
+kill $BGPROCESS
+wait_pid_termination ${RSYSLOG_DYNNAME}${testsrv}.pid
+
+rc=0
+# for each record in mmkubernetes-cache-expire.out.json, see if the matching
+# record is found in $RSYSLOG_OUT_LOG
+$PYTHON -c 'import sys,json
+k8s_srv_port = sys.argv[3]
+expected = {}
+for hsh in json.load(open(sys.argv[1])):
+ if "testid" in hsh:
+ if "kubernetes" in hsh and "master_url" in hsh["kubernetes"]:
+ hsh["kubernetes"]["master_url"] = hsh["kubernetes"]["master_url"].format(k8s_srv_port=k8s_srv_port)
+ expected[hsh["testid"]] = hsh
+rc = 0
+actual = {}
+for line in open(sys.argv[2]):
+ hsh = json.loads(line)
+ if "testid" in hsh:
+ actual[hsh["testid"]] = hsh
+for testid,hsh in expected.items():
+ if not testid in actual:
+ print("Error: record for testid {0} not found in output".format(testid))
+ rc = 1
+ else:
+ for kk,vv in hsh.items():
+ if not kk in actual[testid]:
+ print("Error: key {0} in record for testid {1} not found in output".format(kk, testid))
+ rc = 1
+ elif not vv == actual[testid][kk]:
+ print("Error: value {0} for key {1} in record for testid {2} does not match the expected value {3}".format(str(actual[testid][kk]), kk, testid, str(vv)))
+ rc = 1
+sys.exit(rc)
+' $srcdir/mmkubernetes-cache-expire.out.expected $RSYSLOG_OUT_LOG $k8s_srv_port || rc=$?
+
+if [ -f ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log ] ; then
+ $PYTHON <${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log -c '
+import sys,json
+# key is recordseen, value is hash of stats for that record
+expectedvalues = {
+ 1: {"namespacecachenumentries": 1, "podcachenumentries": 1, "namespacecachehits": 0,
+ "podcachehits": 0, "namespacecachemisses": 1, "podcachemisses": 1},
+ 2: {"namespacecachenumentries": 1, "podcachenumentries": 1, "namespacecachehits": 0,
+ "podcachehits": 1, "namespacecachemisses": 1, "podcachemisses": 1},
+ 3: {"namespacecachenumentries": 1, "podcachenumentries": 1, "namespacecachehits": 0,
+ "podcachehits": 2, "namespacecachemisses": 1, "podcachemisses": 1},
+ 4: {"namespacecachenumentries": 1, "podcachenumentries": 1, "namespacecachehits": 0,
+ "podcachehits": 2, "namespacecachemisses": 2, "podcachemisses": 2},
+}
+for line in sys.stdin:
+ jstart = line.find("{")
+ if jstart >= 0:
+ hsh = json.loads(line[jstart:])
+ if hsh.get("origin") == "mmkubernetes" and hsh["recordseen"] in expectedvalues:
+ expected = expectedvalues[hsh["recordseen"]]
+ for key in expected:
+ if not expected[key] == hsh.get(key):
+ print("Error: expected value [%s] not equal to actual value [%s] in record [%d] for stat [%s]".format(
+ str(expected[key]), str(hsh[key]), hsh["recordseen"], key))
+' || { rc=$?; echo error: expected stats not found in ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log; }
+else
+ echo error: stats file ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log not found
+ rc=1
+fi
+
+if [ ${rc:-0} -ne 0 ]; then
+ echo
+ echo "FAIL: expected data not found. $RSYSLOG_OUT_LOG is:"
+ cat ${RSYSLOG_DYNNAME}.spool/mmk8s_srv.log
+ cat $RSYSLOG_OUT_LOG
+ cat ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/mmkubernetes.supp b/tests/mmkubernetes.supp
new file mode 100644
index 0000000..6afd004
--- /dev/null
+++ b/tests/mmkubernetes.supp
@@ -0,0 +1,16 @@
+{
+ mmkubernetes: says hashtables are leaked at shutdown but they are freed - not sure what is the problem here
+ Memcheck:Leak
+ fun:malloc
+ fun:create_hashtable
+ obj:*
+ obj:*
+ fun:doModInit
+ fun:Load
+ fun:UseObj
+ fun:modInit
+ fun:doModInit
+ fun:Load
+ fun:modulesProcessCnf
+ fun:cnfDoObj
+}
diff --git a/tests/mmkubernetes_test_server.py b/tests/mmkubernetes_test_server.py
new file mode 100644
index 0000000..3f8c384
--- /dev/null
+++ b/tests/mmkubernetes_test_server.py
@@ -0,0 +1,165 @@
+# Used by the mmkubernetes tests
+# This is a simple http server which responds to kubernetes api requests
+# and responds with kubernetes api server responses
+# added 2018-04-06 by richm, released under ASL 2.0
+import os
+import json
+import sys
+
+try:
+ from http.server import HTTPServer, BaseHTTPRequestHandler
+except ImportError:
+ from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+
+ns_template = '''{{
+ "kind": "Namespace",
+ "apiVersion": "v1",
+ "metadata": {{
+ "name": "{namespace_name}",
+ "selfLink": "/api/v1/namespaces/{namespace_name}",
+ "uid": "{namespace_name}-id",
+ "resourceVersion": "2988",
+ "creationTimestamp": "2018-04-09T21:56:39Z",
+ "labels": {{
+ "label.1.key":"label 1 value",
+ "label.2.key":"label 2 value",
+ "label.with.empty.value":""
+ }},
+ "annotations": {{
+ "k8s.io/description": "",
+ "k8s.io/display-name": "",
+ "k8s.io/node-selector": "",
+ "k8s.io/sa.scc.mcs": "s0:c9,c4",
+ "k8s.io/sa.scc.supplemental-groups": "1000080000/10000",
+ "k8s.io/sa.scc.uid-range": "1000080000/10000",
+ "quota.k8s.io/cluster-resource-override-enabled": "false"
+ }}
+ }},
+ "spec": {{
+ "finalizers": [
+ "openshift.io/origin",
+ "kubernetes"
+ ]
+ }},
+ "status": {{
+ "phase": "Active"
+ }}
+}}'''
+
+pod_template = '''{{
+ "kind": "Pod",
+ "apiVersion": "v1",
+ "metadata": {{
+ "name": "{pod_name}",
+ "generateName": "{pod_name}-prefix",
+ "namespace": "{namespace_name}",
+ "selfLink": "/api/v1/namespaces/{namespace_name}/pods/{pod_name}",
+ "uid": "{pod_name}-id",
+ "resourceVersion": "3486",
+ "creationTimestamp": "2018-04-09T21:56:39Z",
+ "labels": {{
+ "component": "{pod_name}-component",
+ "deployment": "{pod_name}-deployment",
+ "deploymentconfig": "{pod_name}-dc",
+ "custom.label": "{pod_name}-label-value",
+ "label.with.empty.value":""
+ }},
+ "annotations": {{
+ "k8s.io/deployment-config.latest-version": "1",
+ "k8s.io/deployment-config.name": "{pod_name}-dc",
+ "k8s.io/deployment.name": "{pod_name}-deployment",
+ "k8s.io/custom.name": "custom value",
+ "annotation.with.empty.value":""
+ }}
+ }},
+ "status": {{
+ "phase": "Running",
+ "hostIP": "172.18.4.32",
+ "podIP": "10.128.0.14",
+ "startTime": "2018-04-09T21:57:39Z"
+ }}
+}}'''
+
+err_template = '''{{
+ "kind": "Status",
+ "apiVersion": "v1",
+ "metadata": {{
+
+ }},
+ "status": "Failure",
+ "message": "{kind} \\\"{objectname}\\\" {err}",
+ "reason": "{reason}",
+ "details": {{
+ "name": "{objectname}",
+ "kind": "{kind}"
+ }},
+ "code": {code}
+}}'''
+
+is_busy = False
+
+class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
+
+ def do_GET(self):
+ # "http://localhost:18443/api/v1/namespaces/namespace-name2"
+ # parse url - either /api/v1/namespaces/$ns_name
+ # or
+ # /api/v1/namespaces/$ns_name/pods/$pod_name
+ global is_busy
+ comps = self.path.split('/')
+ status = 400
+ if len(comps) >= 5 and comps[1] == 'api' and comps[2] == 'v1' and comps[3] == 'namespaces':
+ resp = None
+ hsh = {'namespace_name':comps[4],'objectname':comps[4],'kind':'namespace'}
+ if len(comps) == 5: # namespace
+ resp_template = ns_template
+ status = 200
+ elif len(comps) == 7 and comps[5] == 'pods': # pod
+ hsh['pod_name'] = comps[6]
+ hsh['kind'] = 'pods'
+ hsh['objectname'] = hsh['pod_name']
+ resp_template = pod_template
+ status = 200
+ else:
+ resp = '{{"error":"do not recognize {0}"}}'.format(self.path)
+ if hsh['objectname'].endswith('not-found'):
+ status = 404
+ hsh['reason'] = 'NotFound'
+ hsh['err'] = 'not found'
+ resp_template = err_template
+ elif hsh['objectname'].endswith('busy'):
+ is_busy = not is_busy
+ if is_busy:
+ status = 429
+ hsh['reason'] = 'Busy'
+ hsh['err'] = 'server is too busy'
+ resp_template = err_template
+ elif hsh['objectname'].endswith('error'):
+ status = 500
+ hsh['reason'] = 'Error'
+ hsh['err'] = 'server is failing'
+ resp_template = err_template
+ if not resp:
+ hsh['code'] = status
+ resp = resp_template.format(**hsh)
+ else:
+ resp = '{{"error":"do not recognize {0}"}}'.format(self.path)
+ if not status == 200:
+ self.log_error(resp)
+ self.send_response(status)
+ self.end_headers()
+ self.wfile.write(json.dumps(json.loads(resp), separators=(',',':')).encode())
+
+port = int(sys.argv[1])
+
+httpd = HTTPServer(('localhost', port), SimpleHTTPRequestHandler)
+
+# write "started" to file named in argv[3]
+with open(sys.argv[3], "w") as ff:
+ ff.write("started\n")
+
+# write pid to file named in argv[2]
+with open(sys.argv[2], "w") as ff:
+ ff.write('{0}\n'.format(os.getpid()))
+
+httpd.serve_forever()
diff --git a/tests/mmnormalize_parsesuccess-vg.sh b/tests/mmnormalize_parsesuccess-vg.sh
new file mode 100755
index 0000000..f4f889f
--- /dev/null
+++ b/tests/mmnormalize_parsesuccess-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# added 2019-04-11 by Rainer Gerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/mmnormalize_parsesuccess.sh
diff --git a/tests/mmnormalize_parsesuccess.sh b/tests/mmnormalize_parsesuccess.sh
new file mode 100755
index 0000000..eb945ef
--- /dev/null
+++ b/tests/mmnormalize_parsesuccess.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# added 2019-04-11 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+
+action(type="mmnormalize" rule=
+ ["rule=: %-:char-to{\"extradata\":\":\"}%:00000000:",
+ "rule=: %-:char-to{\"extradata\":\":\"}%:00000010:"] )
+
+if not ($rawmsg contains "rsyslog") then
+ if $parsesuccess == "OK" then
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+ else
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.failed")
+'
+startup
+injectmsg 0 20
+shutdown_when_empty
+wait_shutdown
+content_check "msgnum:00000000:" $RSYSLOG_OUT_LOG
+content_check "msgnum:00000010:" $RSYSLOG_OUT_LOG
+content_check "msgnum:00000001:" $RSYSLOG_DYNNAME.failed
+content_check "msgnum:00000012:" $RSYSLOG_DYNNAME.failed
+exit_test
diff --git a/tests/mmnormalize_processing_test1.sh b/tests/mmnormalize_processing_test1.sh
new file mode 100755
index 0000000..c421adb
--- /dev/null
+++ b/tests/mmnormalize_processing_test1.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/faketime_common.sh
+
+export TZ=TEST+02:00
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="t_file_record" type="string" string="%timestamp:::date-rfc3339% %timestamp:::date-rfc3339% %hostname% %$!v_tag% %$!v_msg%\n")
+template(name="t_file_path" type="string" string="/sb/logs/incoming/%$year%/%$month%/%$day%/svc_%$!v_svc%/ret_%$!v_ret%/os_%$!v_os%/%fromhost-ip%/r_relay1/%$!v_file:::lowercase%.gz\n")
+
+template(name="t_fromhost-ip" type="string" string="%fromhost-ip%")
+template(name="t_analytics_msg_default" type="string" string="%$!v_analytics_prefix%%rawmsg-after-pri%")
+template(name="t_analytics_tag_prefix" type="string" string="%$!v_tag%: ")
+template(name="t_analytics_msg_normalized" type="string" string="%timereported% %$!v_hostname% %$!v_analytics_prefix%%$!v_msg%")
+template(name="t_analytics_msg_normalized_vc" type="string" string="%timereported:1:6% %$year% %timereported:8:$% %$!v_hostname% %$!v_analytics_prefix%%$!v_msg%")
+template(name="t_analytics" type="string" string="[][][%$!v_fromhost-ip%][%timestamp:::date-unixtimestamp%][] %$!v_analytics_msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_processing_tests.rulebase` useRawMsg="on")
+ if ($!v_file == "") then {
+ set $!v_file=$!v_tag;
+ }
+ action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_record")
+ action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_path")
+
+ set $!v_forward="PCI";
+
+ if ($!v_forward contains "PCI") then {
+ if ($!v_fromhost-ip == "") then {
+ set $!v_fromhost-ip=exec_template("t_fromhost-ip");
+ }
+ if ($!v_msg == "" or $!v_tag == "") then {
+ set $!v_analytics_msg=exec_template("t_analytics_msg_default");
+ } else {
+ if ($!v_analytics_prefix == "") then {
+ set $!v_analytics_prefix=exec_template("t_analytics_tag_prefix");
+ }
+ if ($!v_hostname == "") then { # needed for vCenter logs with custom hostname
+ set $!v_hostname=exec_template("t_fromhost-ip");
+ }
+ if ($!v_exception == "VC") then {
+ set $!v_analytics_msg=exec_template("t_analytics_msg_normalized_vc");
+ } else {
+ set $!v_analytics_msg=exec_template("t_analytics_msg_normalized");
+ }
+ }
+ action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_analytics")
+ }
+}
+'
+FAKETIME='2017-03-08 12:53:47' startup
+tcpflood -m1 -M "\"<37>1 2017-03-08T12:53:47+02:00 Host1.domain.com Security - - - SER1 M01 WIN [AUF] Wed Mar 08 11:53:48 2017: N\A/Security/Host1.domain.com/Microsoft-Windows-Security-Auditing (5152) - message\""
+shutdown_when_empty
+wait_shutdown
+echo '2017-03-08T12:53:47+02:00 2017-03-08T12:53:47+02:00 Host1.domain.com Security [AUF] Wed Mar 08 11:53:48 2017: N\A/Security/Host1.domain.com/Microsoft-Windows-Security-Auditing (5152) - message
+/sb/logs/incoming/2017/03/08/svc_SER1/ret_M01/os_WIN/127.0.0.1/r_relay1/security.gz
+[][][127.0.0.1][1488970427][] Mar 8 12:53:47 127.0.0.1 EvntSLog: [AUF] Wed Mar 08 11:53:48 2017: N\A/Security/Host1.domain.com/Microsoft-Windows-Security-Auditing (5152) - message' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/mmnormalize_processing_test2.sh b/tests/mmnormalize_processing_test2.sh
new file mode 100755
index 0000000..7e377fb
--- /dev/null
+++ b/tests/mmnormalize_processing_test2.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/faketime_common.sh
+
+export TZ=TEST+02:00
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="t_file_record" type="string" string="%timestamp:::date-rfc3339% %timestamp:::date-rfc3339% %hostname% %$!v_tag% %$!v_msg%\n")
+template(name="t_file_path" type="string" string="/sb/logs/incoming/%$year%/%$month%/%$day%/svc_%$!v_svc%/ret_%$!v_ret%/os_%$!v_os%/%fromhost-ip%/r_relay1/%$!v_file:::lowercase%.gz\n")
+
+template(name="t_fromhost-ip" type="string" string="%fromhost-ip%")
+template(name="t_analytics_msg_default" type="string" string="%$!v_analytics_prefix%%rawmsg-after-pri%")
+template(name="t_analytics_tag_prefix" type="string" string="%$!v_tag%: ")
+template(name="t_analytics_msg_normalized" type="string" string="%timereported% %$!v_hostname% %$!v_analytics_prefix%%$!v_msg%")
+template(name="t_analytics_msg_normalized_vc" type="string" string="%timereported:1:6% %$year% %timereported:8:$% %$!v_hostname% %$!v_analytics_prefix%%$!v_msg%")
+template(name="t_analytics" type="string" string="[][][%$!v_fromhost-ip%][%timestamp:::date-unixtimestamp%][] %$!v_analytics_msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_processing_tests.rulebase` useRawMsg="on")
+ if ($!v_file == "") then {
+ set $!v_file=$!v_tag;
+ }
+ action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_record")
+ action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_path")
+
+ set $!v_forward="PCI";
+
+ if ($!v_forward contains "PCI") then {
+ if ($!v_fromhost-ip == "") then {
+ set $!v_fromhost-ip=exec_template("t_fromhost-ip");
+ }
+ if ($!v_msg == "" or $!v_tag == "") then {
+ set $!v_analytics_msg=exec_template("t_analytics_msg_default");
+ } else {
+ if ($!v_analytics_prefix == "") then {
+ set $!v_analytics_prefix=exec_template("t_analytics_tag_prefix");
+ }
+ if ($!v_hostname == "") then { # needed for vCenter logs with custom hostname
+ set $!v_hostname=exec_template("t_fromhost-ip");
+ }
+ if ($!v_exception == "VC") then {
+ set $!v_analytics_msg=exec_template("t_analytics_msg_normalized_vc");
+ } else {
+ set $!v_analytics_msg=exec_template("t_analytics_msg_normalized");
+ }
+ }
+ action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_analytics")
+ }
+}
+'
+FAKETIME='2017-03-08 12:18:47' startup
+tcpflood -m1 -M "\"<166>2017-03-08T12:18:47.165Z Host2.domain.com Process1: [FFB87B70 verbose Process1HalCnxHostagent opID=WFU-abfbbece] [WaitForUpdatesDone] Completed callback\""
+shutdown_when_empty
+wait_shutdown
+echo '2017-03-08T12:18:47.165Z 2017-03-08T12:18:47.165Z Host2.domain.com Process1 [FFB87B70 verbose Process1HalCnxHostagent opID=WFU-abfbbece] [WaitForUpdatesDone] Completed callback
+/sb/logs/incoming/2017/03/08/svc_SER2/ret_Y01/os_ESX/127.0.0.1/r_relay1/esx.gz
+[][][127.0.0.1][1488975527][] Mar 8 12:18:47 127.0.0.1 Process1: [FFB87B70 verbose Process1HalCnxHostagent opID=WFU-abfbbece] [WaitForUpdatesDone] Completed callback' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/mmnormalize_processing_test3.sh b/tests/mmnormalize_processing_test3.sh
new file mode 100755
index 0000000..c81dfcd
--- /dev/null
+++ b/tests/mmnormalize_processing_test3.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/faketime_common.sh
+
+export TZ=TEST+01:00
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="t_file_record" type="string" string="%timestamp:::date-rfc3339% %timestamp:::date-rfc3339% %hostname% %$!v_tag% %$!v_msg%\n")
+template(name="t_file_path" type="string" string="/sb/logs/incoming/%$year%/%$month%/%$day%/svc_%$!v_svc%/ret_%$!v_ret%/os_%$!v_os%/%fromhost-ip%/r_relay1/%$!v_file:::lowercase%.gz\n")
+
+template(name="t_fromhost-ip" type="string" string="%fromhost-ip%")
+template(name="t_analytics_msg_default" type="string" string="%$!v_analytics_prefix%%rawmsg-after-pri%")
+template(name="t_analytics_tag_prefix" type="string" string="%$!v_tag%: ")
+template(name="t_analytics_msg_normalized" type="string" string="%timereported% %$!v_hostname% %$!v_analytics_prefix%%$!v_msg%")
+template(name="t_analytics_msg_normalized_vc" type="string" string="%timereported:1:6% %$year% %timereported:8:$% %$!v_hostname% %$!v_analytics_prefix%%$!v_msg%")
+template(name="t_analytics" type="string" string="[][][%$!v_fromhost-ip%][%timestamp:::date-unixtimestamp%][] %$!v_analytics_msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_processing_tests.rulebase` useRawMsg="on")
+ if ($!v_file == "") then {
+ set $!v_file=$!v_tag;
+ }
+ action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_record")
+ action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_path")
+
+ set $!v_forward="PCI";
+
+ if ($!v_forward contains "PCI") then {
+ if ($!v_fromhost-ip == "") then {
+ set $!v_fromhost-ip=exec_template("t_fromhost-ip");
+ }
+ if ($!v_msg == "" or $!v_tag == "") then {
+ set $!v_analytics_msg=exec_template("t_analytics_msg_default");
+ } else {
+ if ($!v_analytics_prefix == "") then {
+ set $!v_analytics_prefix=exec_template("t_analytics_tag_prefix");
+ }
+ if ($!v_hostname == "") then { # needed for vCenter logs with custom hostname
+ set $!v_hostname=exec_template("t_fromhost-ip");
+ }
+ if ($!v_exception == "VC") then {
+ set $!v_analytics_msg=exec_template("t_analytics_msg_normalized_vc");
+ } else {
+ set $!v_analytics_msg=exec_template("t_analytics_msg_normalized");
+ }
+ }
+ action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_analytics")
+ }
+}
+'
+FAKETIME='2017-03-08 14:23:51' startup
+tcpflood -m1 -M "\"<182>Mar 8 14:23:51 host3 audispd: {SER3.local6 Y01 LNX [SRCH ALRT DASH REPT ANOM]} node=host3.domain.com type=SYSCALL msg=audit(1488975831.267:230190721):\""
+shutdown_when_empty
+wait_shutdown
+echo '2017-03-08T14:23:51-01:00 2017-03-08T14:23:51-01:00 host3 audispd node=host3.domain.com type=SYSCALL msg=audit(1488975831.267:230190721):
+/sb/logs/incoming/2017/03/08/svc_SER3/ret_Y01/os_LNX/127.0.0.1/r_relay1/local6.gz
+[][][127.0.0.1][1488986631][] Mar 8 14:23:51 host3 audispd: node=host3.domain.com type=SYSCALL msg=audit(1488975831.267:230190721):' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/mmnormalize_processing_test4.sh b/tests/mmnormalize_processing_test4.sh
new file mode 100755
index 0000000..9362ad1
--- /dev/null
+++ b/tests/mmnormalize_processing_test4.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/faketime_common.sh
+
+export TZ=TEST-02:00
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="t_file_record" type="string" string="%timestamp:::date-rfc3339% %timestamp:::date-rfc3339% %hostname% %$!v_tag% %$!v_msg%\n")
+template(name="t_file_path" type="string" string="/sb/logs/incoming/%$year%/%$month%/%$day%/svc_%$!v_svc%/ret_%$!v_ret%/os_%$!v_os%/%fromhost-ip%/r_relay1/%$!v_file:::lowercase%.gz\n")
+
+ruleset(name="ruleset1") {
+ action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_processing_tests.rulebase` useRawMsg="on")
+ if ($!v_file == "") then {
+ set $!v_file=$!v_tag;
+ }
+ action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_record")
+ action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_path")
+
+}
+'
+FAKETIME='2017-03-08 14:56:37' startup
+tcpflood -m1 -M "\"<187>Mar 8 14:56:37 host4 Process2: {SER4.local7 Y01 LNX [SRCH ALRT DASH REPT ANOM]} (/sb/env/logs/dir1/dir2/log_20170308.log) in 1: X/c79RgpDtrva5we84XHTg== (String)\""
+shutdown_when_empty
+wait_shutdown
+echo '2017-03-08T14:56:37+02:00 2017-03-08T14:56:37+02:00 host4 Process2 in 1: X/c79RgpDtrva5we84XHTg== (String)
+/sb/logs/incoming/2017/03/08/svc_SER4/ret_Y01/os_LNX/127.0.0.1/r_relay1/sb/env/logs/dir1/dir2/log_20170308.log.gz' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/mmnormalize_regex.sh b/tests/mmnormalize_regex.sh
new file mode 100755
index 0000000..d6834d7
--- /dev/null
+++ b/tests/mmnormalize_regex.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2014-11-17 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[mmnormalize_regex.sh\]: test for mmnormalize regex field_type
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="hosts_and_ports" type="string" string="host and port list: %$!hps%\n")
+
+template(name="paths" type="string" string="%$!fragments% %$!user%\n")
+template(name="numbers" type="string" string="nos: %$!some_nos%\n")
+
+module(load="../plugins/mmnormalize/.libs/mmnormalize" allowRegex="on")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_regex.rulebase`)
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="hosts_and_ports")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/regex_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check 'host and port list: 192.168.1.2:80, 192.168.1.3, 192.168.1.4:443, 192.168.1.5'
+exit_test
diff --git a/tests/mmnormalize_regex_defaulted.sh b/tests/mmnormalize_regex_defaulted.sh
new file mode 100755
index 0000000..eb3d760
--- /dev/null
+++ b/tests/mmnormalize_regex_defaulted.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2014-11-17 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[mmnormalize_regex_defaulted.sh\]: test for mmnormalize regex field_type, with allow_regex defaulted
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="hosts_and_ports" type="string" string="host and port list: %$!hps%\n")
+
+template(name="paths" type="string" string="%$!fragments% %$!user%\n")
+template(name="numbers" type="string" string="nos: %$!some_nos%\n")
+
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_regex.rulebase`)
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="hosts_and_ports")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/regex_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+assert_content_missing '192' #several ips in input are 192.168.1.0/24
+exit_test
diff --git a/tests/mmnormalize_regex_disabled.sh b/tests/mmnormalize_regex_disabled.sh
new file mode 100755
index 0000000..9eabbcc
--- /dev/null
+++ b/tests/mmnormalize_regex_disabled.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2014-11-17 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[mmnormalize_regex_disabled.sh\]: test for mmnormalize regex field_type with allow_regex disabled
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="hosts_and_ports" type="string" string="host and port list: %$!hps%\n")
+
+template(name="paths" type="string" string="%$!fragments% %$!user%\n")
+template(name="numbers" type="string" string="nos: %$!some_nos%\n")
+
+module(load="../plugins/mmnormalize/.libs/mmnormalize" allowRegex="off")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_regex.rulebase`)
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="hosts_and_ports")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/regex_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+assert_content_missing '192' #several ips in input are 192.168.1.0/24
+exit_test
diff --git a/tests/mmnormalize_rule_from_array.sh b/tests/mmnormalize_rule_from_array.sh
new file mode 100755
index 0000000..43f52bc
--- /dev/null
+++ b/tests/mmnormalize_rule_from_array.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="norm")
+
+template(name="outfmt" type="string" string="%hostname% %syslogtag%\n")
+
+ruleset(name="norm") {
+ action(type="mmnormalize" rule=["rule=: no longer listening on %ip:ipv4%#%port:number%", "rule=: is sending messages on %ip:ipv4%", "rule=: apfelkuchen"])
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 ubuntu tag1: no longer listening on 127.168.0.1#10514\""
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 debian tag2: is sending messages on 127.168.0.1\""
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 centos tag3: apfelkuchen\""
+shutdown_when_empty
+wait_shutdown
+echo 'ubuntu tag1:
+debian tag2:
+centos tag3:' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/mmnormalize_rule_from_string.sh b/tests/mmnormalize_rule_from_string.sh
new file mode 100755
index 0000000..511da15
--- /dev/null
+++ b/tests/mmnormalize_rule_from_string.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="norm")
+
+template(name="outfmt" type="string" string="%hostname% %syslogtag%\n")
+
+ruleset(name="norm") {
+ action(type="mmnormalize" useRawMsg="on" rule="rule=:%host:word% %tag:char-to:\\x3a%: no longer listening on %ip:ipv4%#%port:number%")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -m1 -M "\"ubuntu tag1: no longer listening on 127.168.0.1#10514\""
+tcpflood -m1 -M "\"debian tag2: no longer listening on 127.168.0.2#10514\""
+tcpflood -m1 -M "\"centos tag3: no longer listening on 192.168.0.1#10514\""
+shutdown_when_empty
+wait_shutdown
+echo 'ubuntu tag1:
+debian tag2:
+centos tag3:' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/mmnormalize_tokenized.sh b/tests/mmnormalize_tokenized.sh
new file mode 100755
index 0000000..55b8db2
--- /dev/null
+++ b/tests/mmnormalize_tokenized.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# added 2014-11-03 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[mmnormalize_tokenized.sh\]: test for mmnormalize tokenized field_type
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="ips" type="string" string="%$.ips%\n")
+
+template(name="paths" type="string" string="%$!fragments% %$!user%\n")
+template(name="numbers" type="string" string="nos: %$!some_nos%\n")
+
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_tokenized.rulebase`)
+if ( $!only_ips != "" ) then {
+ set $.ips = $!only_ips;
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="ips")
+} else if ( $!local_ips != "" ) then {
+ set $.ips = $!local_ips;
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="ips")
+} else if ( $!external_ips != "" ) then {
+ set $.ips = $!external_ips;
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="ips")
+} else if ( $!some_nos != "" ) then {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="numbers")
+} else {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="paths")
+}
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/tokenized_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+cp $RSYSLOG_OUT_LOG /tmp/
+content_check '[ "10.20.30.40", "50.60.70.80", "90.100.110.120", "130.140.150.160" ]'
+content_check '[ "192.168.1.2", "192.168.1.3", "192.168.1.4" ]'
+content_check '[ "10.20.30.40", "50.60.70.80", "190.200.210.220" ]'
+content_check '[ "\/bin", "\/usr\/local\/bin", "\/usr\/bin" ] foo'
+content_check '[ [ [ "10" ] ], [ [ "20" ], [ "30", "40", "50" ], [ "60", "70", "80" ] ], [ [ "90" ], [ "100" ] ] ]'
+exit_test
diff --git a/tests/mmnormalize_variable.sh b/tests/mmnormalize_variable.sh
new file mode 100755
index 0000000..4670d8e
--- /dev/null
+++ b/tests/mmnormalize_variable.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# added 2014-10-31 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[mmnormalize_variable.sh\]: basic test for mmnormalize module variable-support
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="h:%$!hr% m:%$!min% s:%$!sec%\n")
+
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="time_fragment" type="list") {
+ property(name="msg" regex.Expression="[0-9]{2}:[0-9]{2}:[0-9]{2} [A-Z]+" regex.Type="ERE" regex.Match="0")
+}
+
+set $.time_frag = exec_template("time_fragment");
+
+action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_variable.rulebase` variable="$.time_frag")
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/date_time_msg
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "h:13 m:20 s:18"
+exit_test
diff --git a/tests/mmpstrucdata-case.sh b/tests/mmpstrucdata-case.sh
new file mode 100755
index 0000000..97a86b5
--- /dev/null
+++ b/tests/mmpstrucdata-case.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# the goal here is to detect memleaks when structured data is not
+# correctly parsed.
+# This file is part of the rsyslog project, released under ASL 2.0
+# rgerhards, 2015-04-30
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmpstrucdata/.libs/mmpstrucdata")
+module(load="../plugins/imtcp/.libs/imtcp")
+
+template(name="outfmt" type="string" string="SD:%$!RFC5424-SD%\n")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmpstrucdata" sd_name.lowercase="off")
+
+action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -m100 -M "\"<161>1 2003-03-01T01:00:00.000Z mymachine.example.com tcpflood - tag [tcpflood@32473 eventID=\\\"1011\\\"] valid structured data\""
+shutdown_when_empty
+wait_shutdown
+content_check_with_count eventID 100
+exit_test
diff --git a/tests/mmpstrucdata-escaping.sh b/tests/mmpstrucdata-escaping.sh
new file mode 100755
index 0000000..34dfc9a
--- /dev/null
+++ b/tests/mmpstrucdata-escaping.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# rgerhards, 2019-10-07
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmpstrucdata/.libs/mmpstrucdata")
+
+template(name="outfmt" type="string" string="%$!rfc5424-sd%\n")
+
+action(type="mmpstrucdata")
+if $msg contains "TESTMESSAGE" then
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg literal '<85>1 2019-08-27T13:02:58.000+01:00 A/B-896747 ABC LMBNI SUCCESS [origin software="ABC" swVersion="47.1"][ABC@32473 eventType="XYZ:IPIP,9:\"free -m\";" remoteIp="192.0.2.1" singleTick="D'"'"'E" bracket="1\]2"] TESTMESSAGE'
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='{ "origin": { "software": "ABC", "swversion": "47.1" }, "abc@32473": { "eventtype": "XYZ:IPIP,9:\"free -m\";", "remoteip": "192.0.2.1", "singletick": "D'"'"'E", "bracket": "1]2" } }'
+cmp_exact
+exit_test
diff --git a/tests/mmpstrucdata-invalid-vg.sh b/tests/mmpstrucdata-invalid-vg.sh
new file mode 100755
index 0000000..7b03d02
--- /dev/null
+++ b/tests/mmpstrucdata-invalid-vg.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# the goal here is to detect memleaks when structured data is not
+# correctly parsed.
+# This file is part of the rsyslog project, released under ASL 2.0
+# rgerhards, 2015-04-30
+. ${srcdir:=.}/diag.sh init
+#skip_platform "FreeBSD" "This test currently does not work on FreeBSD."
+export USE_VALGRIND="YES" # this test only makes sense with valgrind enabled
+# uncomment below to set special valgrind options
+#export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all"
+
+generate_conf
+add_conf '
+module(load="../plugins/mmpstrucdata/.libs/mmpstrucdata")
+module(load="../plugins/imtcp/.libs/imtcp")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmpstrucdata")
+if $msg contains "msgnum" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+# we use different message counts as this hopefully aids us
+# in finding which sample is leaking. For this, check the number
+# of blocks lost and see what set they match.
+tcpflood -m100 -M "\"<161>1 2003-03-01T01:00:00.000Z mymachine.example.com tcpflood - tag [tcpflood@32473 MSGNUM] invalid structured data!\""
+tcpflood -m200 -M "\"<161>1 2003-03-01T01:00:00.000Z mymachine.example.com tcpflood - tag [tcpflood@32473 MSGNUM ] invalid structured data!\""
+tcpflood -m300 -M "\"<161>1 2003-03-01T01:00:00.000Z mymachine.example.com tcpflood - tag [tcpflood@32473 MSGNUM= ] invalid structured data!\""
+tcpflood -m400 -M "\"<161>1 2003-03-01T01:00:00.000Z mymachine.example.com tcpflood - tag [tcpflood@32473 = ] invalid structured data!\""
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/mmpstrucdata-vg.sh b/tests/mmpstrucdata-vg.sh
new file mode 100755
index 0000000..a9ab7d4
--- /dev/null
+++ b/tests/mmpstrucdata-vg.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# rgerhards, 2013-11-22
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[mmpstrucdata.sh\]: testing mmpstrucdata
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmpstrucdata/.libs/mmpstrucdata")
+module(load="../plugins/imtcp/.libs/imtcp")
+
+template(name="outfmt" type="string" string="%$!rfc5424-sd!tcpflood@32473!msgnum%\n")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmpstrucdata")
+if $msg contains "msgnum" then
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup_vg
+sleep 1
+tcpflood -m100 -y
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown_vg
+check_exit_vg
+seq_check 0 99
+exit_test
diff --git a/tests/mmpstrucdata.sh b/tests/mmpstrucdata.sh
new file mode 100755
index 0000000..79e3403
--- /dev/null
+++ b/tests/mmpstrucdata.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# rgerhards, 2013-11-22
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmpstrucdata/.libs/mmpstrucdata")
+module(load="../plugins/imtcp/.libs/imtcp")
+
+template(name="outfmt" type="string" string="%$!rfc5424-sd!tcpflood@32473!msgnum%\n")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmpstrucdata")
+if $msg contains "msgnum" then
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m100 -y
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 99
+exit_test
diff --git a/tests/mmrm1stspace-basic.sh b/tests/mmrm1stspace-basic.sh
new file mode 100755
index 0000000..0b070e3
--- /dev/null
+++ b/tests/mmrm1stspace-basic.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+module(load="../plugins/mmrm1stspace/.libs/mmrm1stspace")
+template(name="outfmt" type="string" string="-%msg%-\n")
+action(type="mmrm1stspace")
+:syslogtag, contains, "tag" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:2\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag:msgnum:3\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag4:\""
+shutdown_when_empty
+wait_shutdown
+echo '-msgnum:1-
+- msgnum:2-
+-msgnum:3-
+--' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/mmtaghostname_server.sh b/tests/mmtaghostname_server.sh
new file mode 100755
index 0000000..de8ab85
--- /dev/null
+++ b/tests/mmtaghostname_server.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# add 2016-12-07 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/mmtaghostname/.libs/mmtaghostname")
+global(localhostname="frontAPP")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset")
+template(name="test" type="string" string="tag: %syslogtag%, server: %hostname%, msg: %msg%\n")
+ruleset(name="ruleset") {
+ action(type="mmtaghostname" forcelocalhostname="on")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="test")
+}
+'
+startup
+tcpflood -m1 -M "\"<189>1 2019-03-03T16:09:56.185+00:00 server app 123.4 msgid - %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)\""
+shutdown_when_empty
+wait_shutdown
+echo 'tag: app[123.4], server: frontAPP, msg: %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
+
diff --git a/tests/mmtaghostname_tag.sh b/tests/mmtaghostname_tag.sh
new file mode 100755
index 0000000..a63425a
--- /dev/null
+++ b/tests/mmtaghostname_tag.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# add 2016-12-07 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/mmtaghostname/.libs/mmtaghostname")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset")
+template(name="test" type="string" string="tag: %syslogtag%, server: %hostname%, msg: %msg%\n")
+ruleset(name="ruleset") {
+ action(type="mmtaghostname" tag="source-imtcp")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="test")
+}
+'
+startup
+tcpflood -m1 -M "\"<189>1 2019-03-03T16:09:56.185+00:00 server app 123.4 msgid - %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)\""
+shutdown_when_empty
+wait_shutdown
+echo 'tag: source-imtcp, server: server, msg: %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
+
diff --git a/tests/mmutf8fix_no_error.sh b/tests/mmutf8fix_no_error.sh
new file mode 100755
index 0000000..549c330
--- /dev/null
+++ b/tests/mmutf8fix_no_error.sh
@@ -0,0 +1,96 @@
+#!/bin/bash
+# add 2018-10-10 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/mmutf8fix/.libs/mmutf8fix")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing")
+
+ruleset(name="testing") {
+ action(type="mmutf8fix" replacementChar="?")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}'
+
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: this is a test message
+<129>Mar 10 01:00:00 172.20.245.8 tag: valid mixed length UTF-8: foo bar řÃꙀ䆑ðŒ°ðž¨
+<129>Mar 10 01:00:00 172.20.245.8 tag: valid 2-byte UTF-8: řÃ
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong = 0x00) 0xC0 0x80: 
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong = 0x2E) 0xC0 0xAE: À®
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong = 0x4E) 0xC1 0x8E: ÁŽ
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong, invalid continuation) 0xC0 0xEE: Àî
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong, invalid continuation but valid utf8) 0xC0 0x2E: À.
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong, invalid continuation but valid utf8) 0xC0 0xC2 0xA7: ˤ
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong, not enough bytes) 0xC0: À
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (invalid continuation) 0xC2 0xEE: Âî
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (invalid continuation but valid utf8) 0xC2 0x2E: Â.
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (invalid continuation but valid utf8) 0xC2 0xC2 0xA7: §
+<129>Mar 10 01:00:00 172.20.245.8 tag: valid 3-byte UTF-8: Ꙁ䆑
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (overlong = 0x2E) 0xE0 0x80 0xAE: à€®
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (overlong = 0x2E0) 0xE0 0x8B 0xA0: à‹ 
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 2nd continuation) 0xE0 0xE2 0x81: àâ
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xE0 0x41 0xA7: àA§
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xE0 0xC2 0xA7: à§
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 3rd continuation) 0xE1 0x85 0xE1: á…á
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xE1 0x85 0x41: á…A
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xE1 0x85 0xD5 0xB6: á…Õ¶
+<129>Mar 10 01:00:00 172.20.245.8 tag: valid 4-byte UTF-8: ðŒ°ðž¨
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (overlong = 0x2E) 0xF0 0x80 0x80 0xAE: ð€€®
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (overlong = 0x2E0) 0xF0 0x80 0x8B 0xA0: ð€‹ 
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (overlong = 0x2E00) 0xF0 0x82 0xB8 0x80: ð‚¸€
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xF0 0x41 0xC5 0xB0: ðAÅ°
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xF0 0xEC 0x8C 0xB0: ð쌰
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xF0 0x90 0xC5 0xB0: ðÅ°
+<129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (invalid 4rd continuation but valid utf8) 0xF0 0x90 0xC5 0x2E: ðŒ.
+<129>Mar 10 01:00:00 172.20.245.8 tag: special characters: ??%%,,..
+<129>Mar 10 01:00:00 172.20.245.8 tag: numbers: 1234567890\""
+
+shutdown_when_empty
+wait_shutdown
+echo ' this is a test message
+ valid mixed length UTF-8: foo bar řÃꙀ䆑ðŒ°ðž¨
+ valid 2-byte UTF-8: řÃ
+ invalid 2-byte UTF-8 (overlong = 0x00) 0xC0 0x80: ??
+ invalid 2-byte UTF-8 (overlong = 0x2E) 0xC0 0xAE: ??
+ invalid 2-byte UTF-8 (overlong = 0x4E) 0xC1 0x8E: ??
+ invalid 2-byte UTF-8 (overlong, invalid continuation) 0xC0 0xEE: ??
+ invalid 2-byte UTF-8 (overlong, invalid continuation but valid utf8) 0xC0 0x2E: ?.
+ invalid 2-byte UTF-8 (overlong, invalid continuation but valid utf8) 0xC0 0xC2 0xA7: ?§
+ invalid 2-byte UTF-8 (overlong, not enough bytes) 0xC0: ?
+ invalid 2-byte UTF-8 (invalid continuation) 0xC2 0xEE: ??
+ invalid 2-byte UTF-8 (invalid continuation but valid utf8) 0xC2 0x2E: ?.
+ invalid 2-byte UTF-8 (invalid continuation but valid utf8) 0xC2 0xC2 0xA7: ?§
+ valid 3-byte UTF-8: Ꙁ䆑
+ invalid 3-byte UTF-8 (overlong = 0x2E) 0xE0 0x80 0xAE: ???
+ invalid 3-byte UTF-8 (overlong = 0x2E0) 0xE0 0x8B 0xA0: ???
+ invalid 3-byte UTF-8 (invalid 2nd continuation) 0xE0 0xE2 0x81: ???
+ invalid 3-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xE0 0x41 0xA7: ?A?
+ invalid 3-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xE0 0xC2 0xA7: ?§
+ invalid 3-byte UTF-8 (invalid 3rd continuation) 0xE1 0x85 0xE1: ???
+ invalid 3-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xE1 0x85 0x41: ??A
+ invalid 3-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xE1 0x85 0xD5 0xB6: ??Õ¶
+ valid 4-byte UTF-8: ðŒ°ðž¨
+ invalid 4-byte UTF-8 (overlong = 0x2E) 0xF0 0x80 0x80 0xAE: ????
+ invalid 4-byte UTF-8 (overlong = 0x2E0) 0xF0 0x80 0x8B 0xA0: ????
+ invalid 4-byte UTF-8 (overlong = 0x2E00) 0xF0 0x82 0xB8 0x80: ????
+ invalid 4-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xF0 0x41 0xC5 0xB0: ?AÅ°
+ invalid 4-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xF0 0xEC 0x8C 0xB0: ?쌰
+ invalid 4-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xF0 0x90 0xC5 0xB0: ??Å°
+ invalid 4-byte UTF-8 (invalid 4rd continuation but valid utf8) 0xF0 0x90 0xC5 0x2E: ???.
+ special characters: ??%%,,..
+ numbers: 1234567890' > "$RSYSLOG_OUT_LOG.expect"
+
+if ! cmp "$RSYSLOG_OUT_LOG.expect" $RSYSLOG_OUT_LOG; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG diff:"
+ # Use LANG=C for binary matching
+ LANG=C diff --text -u "$RSYSLOG_OUT_LOG.expect" $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
+
+exit 0
diff --git a/tests/msg-deadlock-headerless-noappname.sh b/tests/msg-deadlock-headerless-noappname.sh
new file mode 100755
index 0000000..1ac847a
--- /dev/null
+++ b/tests/msg-deadlock-headerless-noappname.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# this checks against a situation where a deadlock was caused in
+# practice.
+# added 2018-10-17 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="input")
+
+ruleset(name="input") {
+ set $!tag = $app-name;
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+startup
+tcpflood -p $TCPFLOOD_PORT -M "[2018-10-16 09:59:13] ping pong"
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+exit_test
diff --git a/tests/msgdup.sh b/tests/msgdup.sh
new file mode 100755
index 0000000..9a94987
--- /dev/null
+++ b/tests/msgdup.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# This tests the border case that a message is exactly as large as the default
+# buffer size (101 chars) and is reduced in size afterwards. This has been seen
+# in practice.
+# see also https://github.com/rsyslog/rsyslog/issues/1658
+# Copyright (C) 2017 by Rainer Gerhards, released under ASL 2.0 (2017-07-11)
+. ${srcdir:=.}/diag.sh init
+check_logger_has_option_d
+generate_conf
+add_conf '
+module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off")
+input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+ruleset(name="rs" queue.type="LinkedList") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+ stop
+}
+
+*.=notice call rs
+'
+startup
+logger -d -u $RSYSLOG_DYNNAME-testbench_socket -t RSYSLOG_TESTBENCH 'test 01234567890123456789012345678901234567890123456789012345
+' #Note: LF at end of message is IMPORTANT, it is bug triggering condition
+# the sleep below is needed to prevent too-early termination of rsyslogd
+./msleep 100
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+export EXPECTED=" test 01234567890123456789012345678901234567890123456789012345"
+cmp_exact $RSYSLOG_OUT_LOG
+exit_test
diff --git a/tests/msgdup_props.sh b/tests/msgdup_props.sh
new file mode 100755
index 0000000..f9ea448
--- /dev/null
+++ b/tests/msgdup_props.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+# This test checks the MsgDup() properly copies all properties.
+# added 2019-06-26 by Rgerhards. Released under ASL 2.0
+
+# create the pipe and start a background process that copies data from
+# it to the "regular" work file
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MainMsgQueueTimeoutShutdown 10000
+template(name="all_properties" type="list") {
+ property(format="jsonf" name="fromhost") constant(value="\n")
+ property(format="jsonf" name="fromhost-ip") constant(value="\n")
+ property(format="jsonf" name="hostname") constant(value="\n")
+ property(format="jsonf" name="inputname") constant(value="\n")
+ property(format="jsonf" name="msg") constant(value="\n")
+ property(format="jsonf" name="msgid") constant(value="\n")
+ property(format="jsonf" name="$!" outname="globalvar") constant(value="\n")
+ property(format="jsonf" name="$." outname="localvar") constant(value="\n")
+ property(format="jsonf" name="pri") constant(value="\n")
+ property(format="jsonf" name="pri-text") constant(value="\n")
+ property(format="jsonf" name="procid") constant(value="\n")
+ property(format="jsonf" name="protocol-version") constant(value="\n")
+ property(format="jsonf" name="rawmsg-after-pri") constant(value="\n")
+ property(format="jsonf" name="rawmsg") constant(value="\n")
+ property(format="jsonf" name="structured-data") constant(value="\n")
+ property(format="jsonf" name="syslogtag") constant(value="\n")
+ property(format="jsonf" name="timegenerated") constant(value="\n")
+ property(format="jsonf" name="timegenerated" dateformat="rfc3339") constant(value="\n")
+ property(format="jsonf" name="timereported") constant(value="\n")
+ property(format="jsonf" name="timereported" dateformat="rfc3339") constant(value="\n")
+}
+
+ruleset(name="rs_with_queue" queue.type="LinkedList" queue.size="10000") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="all_properties")
+ # works on a duplicated message thanks to the queue
+}
+
+set $!var="msg var";
+set $.var="local var";
+if $msg contains "msgnum:" then {
+ call rs_with_queue
+ action(type="omfile" file="'$RSYSLOG2_OUT_LOG'" template="all_properties")
+ # works on original, non-duplicated, message
+}
+'
+startup
+injectmsg 0 1 # we need only one message to check the properties
+shutdown_when_empty
+wait_shutdown
+
+cmp "$RSYSLOG_OUT_LOG" "$RSYSLOG2_OUT_LOG"
+if [ $? -ne 0 ]; then
+ printf 'ERROR: output files do not match!\n'
+ printf '################# %s is:\n' "$RSYSLOG_OUT_LOG"
+ cat -n "$RSYSLOG_OUT_LOG"
+ printf '################# %s is:\n' "$RSYSLOG2_OUT_LOG"
+ cat -n "$RSYSLOG2_OUT_LOG"
+ printf '\n#################### diff is:\n'
+ diff "$RSYSLOG_OUT_LOG" "$RSYSLOG2_OUT_LOG"
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/msgvar-concurrency-array-event.tags.sh b/tests/msgvar-concurrency-array-event.tags.sh
new file mode 100755
index 0000000..dfa6ac3
--- /dev/null
+++ b/tests/msgvar-concurrency-array-event.tags.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Test concurrency of message variables
+# Added 2015-11-03 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+export TCPFLOOD_EXTRA_OPTS="-M'msg:msg: 1:2, 3:4, 5:6, 7:8 b test'"
+echo ===============================================================================
+echo \[msgvar-concurrency-array-event.tags.sh\]: testing concurrency of local variables
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%$!%\n")
+
+#action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt" queue.type="linkedList")
+action(type="mmnormalize" ruleBase="testsuites/msgvar-concurrency-array-event.tags.rulebase")
+if $msg contains "msg:" then {
+# set $!tree!here!nbr = field($msg, 58, 2); # Delimiter = :
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt" queue.type="linkedList")
+ set $!tree!here!save = $!tree!here!nbr;
+ set $!tree!here!nbr = "";
+ set $!tree!here!nbr = $!tree!here!save;
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" queue.type="linkedList")
+}
+'
+startup
+sleep 1
+tcpflood -m500000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+#seq_check 0 499999
+exit_test
diff --git a/tests/msgvar-concurrency-array.sh b/tests/msgvar-concurrency-array.sh
new file mode 100755
index 0000000..ef6ae30
--- /dev/null
+++ b/tests/msgvar-concurrency-array.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Test concurrency of message variables
+# Added 2015-11-03 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+export TCPFLOOD_EXTRA_OPTS="-M'msg:msg: 1:2, 3:4, 5:6, 7:8 b test'"
+echo ===============================================================================
+echo \[msgvar-concurrency-array.sh\]: testing concurrency of local variables
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/mmnormalize/.libs/mmnormalize")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%$!%\n")
+
+#action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt" queue.type="linkedList")
+action(type="mmnormalize" ruleBase="testsuites/msgvar-concurrency-array.rulebase")
+if $msg contains "msg:" then {
+# set $!tree!here!nbr = field($msg, 58, 2); # Delimiter = :
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt" queue.type="linkedList")
+ set $!tree!here!save = $!tree!here!nbr;
+ set $!tree!here!nbr = "";
+ set $!tree!here!nbr = $!tree!here!save;
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" queue.type="linkedList")
+}
+'
+startup
+sleep 1
+tcpflood -m500000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+#seq_check 0 499999
+exit_test
diff --git a/tests/msgvar-concurrency.sh b/tests/msgvar-concurrency.sh
new file mode 100755
index 0000000..57ae0e1
--- /dev/null
+++ b/tests/msgvar-concurrency.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# Test concurrency of message variables
+# Added 2015-11-03 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+uname
+if [ $(uname) = "SunOS" ] ; then
+ echo "This test currently does not work on all flavors of Solaris."
+ exit 77
+fi
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%$!tree!here!nbr%\n")
+
+if $msg contains "msgnum:" then {
+ set $!tree!here!nbr = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt"
+ queue.type="linkedList")
+
+ set $!tree!here!save = $!tree!here!nbr;
+ set $!tree!here!nbr = "";
+ set $!tree!here!nbr = $!tree!here!save;
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -m500000
+shutdown_when_empty
+wait_shutdown
+seq_check 0 499999
+exit_test
diff --git a/tests/msleep.c b/tests/msleep.c
new file mode 100644
index 0000000..98dbece
--- /dev/null
+++ b/tests/msleep.c
@@ -0,0 +1,58 @@
+/* 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>
+#if defined(__FreeBSD__)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#if defined(HAVE_SYS_SELECT_H)
+#include <sys/select.h>
+#endif
+
+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/msleep_usage_output.sh b/tests/msleep_usage_output.sh
new file mode 100755
index 0000000..a3bae14
--- /dev/null
+++ b/tests/msleep_usage_output.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+
+./msleep &> $RSYSLOG_DYNNAME.output
+grep "usage: msleep" $RSYSLOG_DYNNAME.output
+
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated"
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/multiple_lookup_tables-vg.sh b/tests/multiple_lookup_tables-vg.sh
new file mode 100755
index 0000000..4ab23b1
--- /dev/null
+++ b/tests/multiple_lookup_tables-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# added 2016-01-20 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/multiple_lookup_tables.sh
diff --git a/tests/multiple_lookup_tables.sh b/tests/multiple_lookup_tables.sh
new file mode 100755
index 0000000..ec1843a
--- /dev/null
+++ b/tests/multiple_lookup_tables.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# test for multiple lookup-table and HUP based reloading of it
+# added 2016-01-20 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+lookup_table(name="xlate_0" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl")
+lookup_table(name="xlate_1" file="'$RSYSLOG_DYNNAME'.xlate_1.lkp_tbl")
+
+template(name="outfmt" type="string" string="- %msg% 0_%$.lkp_0% 1_%$.lkp_1%\n")
+
+set $.lkp_0 = lookup("xlate_0", $msg);
+set $.lkp_1 = lookup("xlate_1", $msg);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate_1.lkp_tbl
+startup
+injectmsg 0 3
+wait_queueempty
+content_check "msgnum:00000000: 0_foo_old 1_foo_old"
+content_check "msgnum:00000001: 0_bar_old 1_bar_old"
+assert_content_missing "baz"
+cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 3
+wait_queueempty
+content_check "msgnum:00000000: 0_foo_new 1_foo_old"
+content_check "msgnum:00000001: 0_bar_new 1_bar_old"
+content_check "msgnum:00000002: 0_baz"
+assert_content_missing "1_baz"
+cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate_1.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 3
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "msgnum:00000000: 0_foo_new 1_foo_new"
+content_check "msgnum:00000001: 0_bar_new 1_bar_new"
+content_check "msgnum:00000002: 0_baz 1_baz"
+exit_test
diff --git a/tests/mysql-actq-mt-withpause-vg.sh b/tests/mysql-actq-mt-withpause-vg.sh
new file mode 100755
index 0000000..aba33ad
--- /dev/null
+++ b/tests/mysql-actq-mt-withpause-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/mysql-actq-mt-withpause.sh
diff --git a/tests/mysql-actq-mt-withpause.sh b/tests/mysql-actq-mt-withpause.sh
new file mode 100755
index 0000000..e613ee2
--- /dev/null
+++ b/tests/mysql-actq-mt-withpause.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# test for mysql with multithread actionq
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=150000
+generate_conf
+add_conf '
+module(load="../plugins/ommysql/.libs/ommysql")
+
+:msg, contains, "msgnum:" {
+ action(type="ommysql" server="127.0.0.1"
+ db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench"
+ queue.size="10000" queue.type="linkedList"
+ queue.workerthreads="5"
+ queue.workerthreadMinimumMessages="500"
+ queue.timeoutWorkerthreadShutdown="1000"
+ queue.timeoutEnqueue="20000"
+ )
+}
+'
+mysql_prep_for_test
+startup
+injectmsg 0 50000
+wait_queueempty
+echo waiting for worker threads to timeout
+./msleep 3000
+injectmsg 50000 50000
+wait_queueempty
+echo waiting for worker threads to timeout
+./msleep 2000
+injectmsg 100000 50000
+shutdown_when_empty
+wait_shutdown
+mysql_get_data
+seq_check
+mysql_cleanup_test
+exit_test
diff --git a/tests/mysql-actq-mt.sh b/tests/mysql-actq-mt.sh
new file mode 100755
index 0000000..c54afb4
--- /dev/null
+++ b/tests/mysql-actq-mt.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# test for mysql with multithread actionq
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=150000
+generate_conf
+add_conf '
+module(load="../plugins/ommysql/.libs/ommysql")
+
+:msg, contains, "msgnum:" {
+ action(type="ommysql" server="127.0.0.1"
+ db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench"
+ queue.size="10000" queue.type="linkedList"
+ queue.workerthreads="5"
+ queue.workerthreadMinimumMessages="500"
+ queue.timeoutWorkerthreadShutdown="1000"
+ queue.timeoutEnqueue="10000"
+ queue.timeoutShutdown="30000"
+ )
+}
+'
+mysql_prep_for_test
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+mysql_get_data
+seq_check
+mysql_cleanup_test
+exit_test
diff --git a/tests/mysql-asyn-vg.sh b/tests/mysql-asyn-vg.sh
new file mode 100755
index 0000000..15d0998
--- /dev/null
+++ b/tests/mysql-asyn-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/mysql-asyn.sh
diff --git a/tests/mysql-asyn.sh b/tests/mysql-asyn.sh
new file mode 100755
index 0000000..8f2bd65
--- /dev/null
+++ b/tests/mysql-asyn.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# asyn test for mysql functionality (running on async action queue)
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+generate_conf
+add_conf '
+$ModLoad ../plugins/ommysql/.libs/ommysql
+$ActionQueueType LinkedList
+$ActionQueueTimeoutEnqueue 20000
+:msg, contains, "msgnum:" :ommysql:127.0.0.1,'$RSYSLOG_DYNNAME',rsyslog,testbench;
+'
+mysql_prep_for_test
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+mysql_get_data
+seq_check
+mysql_cleanup_test
+exit_test
diff --git a/tests/mysql-basic-cnf6.sh b/tests/mysql-basic-cnf6.sh
new file mode 100755
index 0000000..1fd3e5c
--- /dev/null
+++ b/tests/mysql-basic-cnf6.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+generate_conf
+add_conf '
+$ModLoad ../plugins/ommysql/.libs/ommysql
+if $msg contains "msgnum" then {
+ action(type="ommysql" server="127.0.0.1"
+ db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench")
+}
+'
+mysql_prep_for_test
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+mysql_get_data
+seq_check
+mysql_cleanup_test
+exit_test
diff --git a/tests/mysql-basic-vg.sh b/tests/mysql-basic-vg.sh
new file mode 100755
index 0000000..c30e430
--- /dev/null
+++ b/tests/mysql-basic-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/mysql-basic.sh
diff --git a/tests/mysql-basic.sh b/tests/mysql-basic.sh
new file mode 100755
index 0000000..b6ac85f
--- /dev/null
+++ b/tests/mysql-basic.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# basic test for mysql functionality
+. ${srcdir:=.}/diag.sh init
+ # DEBUGGING - REMOVE ME #
+ ls -l mysql*log
+ sudo cat /var/log/mysql/error.log ## TODO: remove me
+ df -h
+export NUMMESSAGES=5000
+generate_conf
+add_conf '
+$ModLoad ../plugins/ommysql/.libs/ommysql
+:msg, contains, "msgnum:" :ommysql:127.0.0.1,'$RSYSLOG_DYNNAME',rsyslog,testbench;
+'
+mysql_prep_for_test
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+mysql_get_data
+seq_check
+mysql_cleanup_test
+exit_test
diff --git a/tests/mysqld-start.sh b/tests/mysqld-start.sh
new file mode 100755
index 0000000..b4f9470
--- /dev/null
+++ b/tests/mysqld-start.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# This is not a real test, but a script to start mysql. It is
+# implemented as test so that we can start mysql at the time we need
+# it (do so via Makefile.am).
+# Copyright (C) 2018 Rainer Gerhards and Adiscon GmbH
+# Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+echo pre-start
+ps -ef |grep bin.mysqld
+if [ "$MYSQLD_START_CMD" == "" ]; then
+ exit_test # no start needed
+fi
+
+test_error_exit_handler() {
+ set -x; set -v
+ printf 'mysqld startup failed, log is:\n'
+ $SUDO cat /var/log/mysql/error.log
+}
+
+printf 'starting mysqld...\n'
+$MYSQLD_START_CMD &
+wait_startup_pid /var/run/mysqld/mysqld.pid
+$SUDO tail -n30 /var/log/mysql/error.log
+printf 'preparing mysqld for testbench use...\n'
+$SUDO ${srcdir}/../devtools/prep-mysql-db.sh
+printf 'done, mysql ready for testbench\n'
+ps -ef |grep bin.mysqld
+exit_test
diff --git a/tests/mysqld-stop.sh b/tests/mysqld-stop.sh
new file mode 100755
index 0000000..6ac76dd
--- /dev/null
+++ b/tests/mysqld-stop.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+# This is not a real test, but a script to stop mysql. It is
+# implemented as test so that we can stop mysql at the time we need
+# it (do so via Makefile.am).
+# Copyright (C) 2018 Rainer Gerhards and Adiscon GmbH
+# Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+if [ "$MYSQLD_STOP_CMD" == "" ]; then
+ exit_test
+fi
+printf 'stopping mysqld...\n'
+eval $MYSQLD_STOP_CMD
+sleep 1 # cosmetic: give mysqld a chance to emit shutdown message
+exit_test
diff --git a/tests/nested-call-shutdown.sh b/tests/nested-call-shutdown.sh
new file mode 100755
index 0000000..f82c6b5
--- /dev/null
+++ b/tests/nested-call-shutdown.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# addd 2017-10-18 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omtesting/.libs/omtesting")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+ruleset(name="rs3" queue.type="linkedList") {
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+
+ruleset(name="rs2" queue.type="linkedList") {
+ call rs3
+}
+
+ruleset(name="rs1" queue.type="linkedList") {
+ call rs2
+ :omtesting:sleep 0 1000
+}
+
+if $msg contains "msgnum:" then call rs1
+'
+startup
+#tcpflood -p'$TCPFLOOD_PORT' -m10000
+injectmsg 0 1000
+shutdown_immediate
+wait_shutdown
+# wo do not check reception - the main point is that we do not abort. The actual
+# message count is unknown (as the point is to shut down while still in processing).
+exit_test
diff --git a/tests/no-dynstats-json.sh b/tests/no-dynstats-json.sh
new file mode 100755
index 0000000..245e894
--- /dev/null
+++ b/tests/no-dynstats-json.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# added 2016-03-10 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[no-dynstats-json.sh\]: test for verifying stats are reported correctly in json format in absence of any dynstats buckets being configured
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="json")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+custom_content_check '{ "name": "global", "origin": "dynstats", "values": { } }' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/no-dynstats.sh b/tests/no-dynstats.sh
new file mode 100755
index 0000000..0d9bc4f
--- /dev/null
+++ b/tests/no-dynstats.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# added 2016-03-10 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[no-dynstats.sh\]: test for verifying stats are reported correctly in legacy format in absence of any dynstats buckets being configured
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+custom_content_check 'global: origin=dynstats' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/no-parser-errmsg.sh b/tests/no-parser-errmsg.sh
new file mode 100755
index 0000000..2cae383
--- /dev/null
+++ b/tests/no-parser-errmsg.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# add 2017-03-06 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset")
+template(name="test" type="string" string="tag: %syslogtag%, pri: %pri%, syslogfacility: %syslogfacility%, syslogseverity: %syslogseverity% msg: %msg%\n")
+ruleset(name="ruleset" parser="rsyslog.rfc5424") {
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="test")
+}
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+grep 'one message could not be processed by any parser' $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/no-parser-vg.sh b/tests/no-parser-vg.sh
new file mode 100755
index 0000000..a52aced
--- /dev/null
+++ b/tests/no-parser-vg.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# add 2017-03-06 by Rainer Gerhards, released under ASL 2.0
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset")
+ruleset(name="ruleset" parser="rsyslog.rfc5424") {
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)
+}
+'
+startup_vg
+tcpflood -m10
+shutdown_when_empty
+wait_shutdown_vg
+# note: we just check the valgrind output, the log file itself does not
+# interest us
+
+exit_test
diff --git a/tests/now-unixtimestamp.sh b/tests/now-unixtimestamp.sh
new file mode 100755
index 0000000..58058fd
--- /dev/null
+++ b/tests/now-unixtimestamp.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# addd 2016-02-23 by RGerhards, released under ASL 2.0
+# requires faketime
+echo \[now-utc\]: test \$NOW-UTC
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $.tnow = $$now-unixtimestamp + 1;
+
+template(name="outfmt" type="string"
+ string="%$now-unixtimestamp%,%$.tnow%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+
+. $srcdir/faketime_common.sh
+
+export TZ=TEST-02:00
+
+FAKETIME='2016-01-01 01:00:00' startup
+# what we send actually is irrelevant, as we just use system properties.
+# but we need to send one message in order to gain output!
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="1451602800,1451602801"
+cmp_exact
+exit_test
diff --git a/tests/now-utc-casecmp.sh b/tests/now-utc-casecmp.sh
new file mode 100755
index 0000000..8eda3a1
--- /dev/null
+++ b/tests/now-utc-casecmp.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# addd 2016-02-23 by RGerhards, released under ASL 2.0
+# requires faketime
+echo \[now-utc-casecmp\]: test \$year-utc, \$month-utc, \$day-utc
+. ${srcdir:=.}/diag.sh init
+
+. $srcdir/faketime_common.sh
+
+export TZ=TEST-02:00
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%$Now%:%$Year%-%$Month%-%$Day%,%$Now-utc%:%$Year-utc%-%$Month-utc%-%$Day-utc%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+FAKETIME='2016-01-01 01:00:00' startup
+# what we send actually is irrelevant, as we just use system properties.
+# but we need to send one message in order to gain output!
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "2016-01-01:2016-01-01,2015-12-31:2015-12-31" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error-exit 1
+fi;
+
+
+exit_test
diff --git a/tests/now-utc-ymd.sh b/tests/now-utc-ymd.sh
new file mode 100755
index 0000000..a8b6ea8
--- /dev/null
+++ b/tests/now-utc-ymd.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# addd 2016-02-23 by RGerhards, released under ASL 2.0
+# requires faketime
+. ${srcdir:=.}/diag.sh init
+echo \[now-utc-ymd\]: test \$year-utc, \$month-utc, \$day-utc
+
+. $srcdir/faketime_common.sh
+
+export TZ=TEST-02:00
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%$year%-%$month%-%$day%,%$year-utc%-%$month-utc%-%$day-utc%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+FAKETIME='2016-01-01 01:00:00' startup
+# what we send actually is irrelevant, as we just use system properties.
+# but we need to send one message in order to gain output!
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="2016-01-01,2015-12-31"
+exit_test
diff --git a/tests/now-utc.sh b/tests/now-utc.sh
new file mode 100755
index 0000000..c21cedc
--- /dev/null
+++ b/tests/now-utc.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# addd 2016-02-23 by RGerhards, released under ASL 2.0
+# requires faketime
+echo \[now-utc\]: test \$NOW-UTC
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%$now%,%$now-utc%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+. $srcdir/faketime_common.sh
+
+export TZ=TEST-02:00
+
+FAKETIME='2016-01-01 01:00:00' startup
+# what we send actually is irrelevant, as we just use system properties.
+# but we need to send one message in order to gain output!
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="2016-01-01,2015-12-31"
+cmp_exact
+exit_test
diff --git a/tests/now_family_utc.sh b/tests/now_family_utc.sh
new file mode 100755
index 0000000..5e081ba
--- /dev/null
+++ b/tests/now_family_utc.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# test $NOW family of system properties
+# addd 2016-01-12 by RGerhards, released under ASL 2.0
+# requires faketime
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%$hour%:%$minute%,%$hour-utc%:%$minute-utc%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+. $srcdir/faketime_common.sh
+
+export TZ=TEST+06:30
+
+FAKETIME='2016-01-01 01:00:00' startup
+# what we send actually is irrelevant, as we just use system properties.
+# but we need to send one message in order to gain output!
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="01:00,07:30"
+cmp_exact
+
+exit_test
diff --git a/tests/omamqp1-basic-vg.sh b/tests/omamqp1-basic-vg.sh
new file mode 100755
index 0000000..7d8d826
--- /dev/null
+++ b/tests/omamqp1-basic-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/omamqp1-basic.sh
diff --git a/tests/omamqp1-basic.sh b/tests/omamqp1-basic.sh
new file mode 100755
index 0000000..ceda533
--- /dev/null
+++ b/tests/omamqp1-basic.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/omamqp1-common.sh
+
+AMQP_URL=${AMQP_URL:-"localhost:5672"}
+NUMMESSAGES=10240
+
+generate_conf
+if [ "${USE_VALGRIND:-}" = YES ] ; then
+ add_conf '
+global(debug.unloadModules="off")
+'
+fi
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../plugins/impstats/.libs/impstats" interval="1"
+ log.file="'"$RSYSLOG_DYNNAME.spool"'/stats.log" log.syslog="off" format="cee")
+module(load="../contrib/omamqp1/.libs/omamqp1")
+
+if $msg contains "msgnum:" then
+ action(type="omamqp1"
+ host="'"$AMQP_URL"'"
+ target="amq.rsyslogtest")
+'
+qdrouterd > $RSYSLOG_DYNNAME.spool/qdrouterd.log 2>&1 & qdrouterdpid=$!
+sleep 5 # give qdrouterd a chance to start up and listen
+# have to start reader before writer - like a pipe - for the client, NUMMESSAGES could
+# be much less than the number of records if batching is used - for the client, it means
+# batches, not records - but there can't be more batches than records
+amqp_simple_recv $AMQP_URL amq.rsyslogtest $NUMMESSAGES > $RSYSLOG_DYNNAME.spool/amqp_simple_recv.out 2>&1 &
+#export RSYSLOG_DEBUG=debug
+#export RSYSLOG_DEBUGLOG=/tmp/rsyslog.debug.log
+startup
+if [ -n "${USE_GDB:-}" ] ; then
+ echo attach gdb here
+ sleep 54321 || :
+fi
+injectmsg 0 $NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+
+timeout=60
+for ii in $( seq 1 $timeout ) ; do
+ if grep -q "msgnum:00*$(( NUMMESSAGES - 1 ))" $RSYSLOG_DYNNAME.spool/amqp_simple_recv.out ; then
+ break
+ fi
+ sleep 1
+done
+kill $qdrouterdpid > /dev/null 2>&1 || kill -9 $qdrouterdpid > /dev/null 2>&1 || :
+# you would think there would be a better way to do this . . .
+kill $( pgrep -f 'python.*simple_recv.py' )
+if [ $ii = $timeout ] ; then
+ echo ERROR: amqp_simple_recv did not receive all $NUMMESSAGES messages in $timeout seconds
+ error_exit 1
+fi
+
+$PYTHON -c 'import sys
+inp = file(sys.argv[1],"r").read()
+last = 0
+idx = inp.find("msgnum:",last)
+while idx > -1:
+ msgstr = inp[(idx+7):(idx+15)]
+ print msgstr
+ last = idx+16
+ idx = inp.find("msgnum:",last)
+' $RSYSLOG_DYNNAME.spool/amqp_simple_recv.out > $RSYSLOG_OUT_LOG
+seq_check
diff --git a/tests/omamqp1-common.sh b/tests/omamqp1-common.sh
new file mode 100644
index 0000000..ec0a6ae
--- /dev/null
+++ b/tests/omamqp1-common.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+# version of qdrouterd to use for test
+QDROUTERD_VERSION=${QDROUTERD_VERSION:-1.7.0}
+# Use of containers isn't necessary for CI, and might not be
+# useful for devs, depending on platform availability.
+# If not using a container for the test, the
+# package will be installed using the platform
+# package manager.
+#USE_CONTAINER=${USE_CONTAINER:-false}
+#CONTAINER_URL=${CONTAINER_URL:-quay.io/interconnectedcloud/qdrouterd:$QDROUTERD_VERSION}
+
+if ! type -p qdrouterd ; then
+ echo no qdrouterd found in PATH $PATH - skipping test
+ exit 0
+fi
+
+ver=$( qdrouterd --version )
+if [ "$ver" = $QDROUTERD_VERSION ] ; then
+ echo found qdrouterd version $ver - continuing
+else
+ echo found qdrouterd version $ver but expected version $QDROUTERD_VERSION - skipping test
+ exit 0
+fi
+
+AMQP_SIMPLE_RECV=${AMQP_SIMPLE_RECV:-/usr/share/proton-0.28.0/examples/python/simple_recv.py}
+
+if [ -f $AMQP_SIMPLE_RECV ] ; then
+ echo found $AMQP_SIMPLE_RECV
+else
+ echo no amqp client $AMQP_SIMPLE_RECV - skipping test
+ exit 0
+fi
+
+AMQP_PYTHON=${AMQP_PYTHON:-python}
+if $AMQP_PYTHON $AMQP_SIMPLE_RECV --help > /dev/null 2>&1 ; then
+ : # good
+elif python3 $AMQP_SIMPLE_RECV --help > /dev/null 2>&1 ; then
+ AMQP_PYTHON=python3
+else
+ echo missing python modules for $AMQP_SIMPLE_RECV - skipping test
+ exit 0
+fi
+
+amqp_simple_recv() {
+ # $1 is host:port (or amqp url if applicable)
+ # $2 is target (e.g. amq.rsyslogtest)
+ # $3 is number of messages to read
+ stdbuf -o 0 $AMQP_PYTHON $AMQP_SIMPLE_RECV -a $1/$2 -m $3
+}
diff --git a/tests/omazureeventhubs-basic-vg.sh b/tests/omazureeventhubs-basic-vg.sh
new file mode 100755
index 0000000..f5552df
--- /dev/null
+++ b/tests/omazureeventhubs-basic-vg.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes --leak-check=full"
+export EXTRA_VALGRIND_SUPPRESSIONS="--suppressions=omazureeventhubs.supp"
+source ${srcdir:-.}/omazureeventhubs-basic.sh
+
diff --git a/tests/omazureeventhubs-basic.sh b/tests/omazureeventhubs-basic.sh
new file mode 100755
index 0000000..0865b7b
--- /dev/null
+++ b/tests/omazureeventhubs-basic.sh
@@ -0,0 +1,123 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=100
+export NUMMESSAGESFULL=$NUMMESSAGES
+export WAITTIMEOUT=20
+
+# REQUIRES EXTERNAL ENVIRONMENT VARIABLES
+if [[ -z "${AZURE_HOST}" ]]; then
+ echo "SKIP: AZURE_HOST environment variable not SET! Example: <yourname>.servicebus.windows.net - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_PORT}" ]]; then
+ echo "SKIP: AZURE_PORT environment variable not SET! Example: 5671 - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_KEY_NAME}" ]]; then
+ echo "SKIP: AZURE_KEY_NAME environment variable not SET! Example: <yourkeyname> - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_KEY}" ]]; then
+ echo "SKIP: AZURE_KEY environment variable not SET! Example: <yourlongkey> - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_CONTAINER}" ]]; then
+ echo "SKIP: AZURE_CONTAINER environment variable not SET! Example: <youreventhubsname> - SKIPPING"
+ exit 77
+fi
+
+export AMQPS_ADRESS="amqps://$AZURE_KEY_NAME:$AZURE_KEY@$AZURE_HOST:$AZURE_PORT/$AZURE_NAME"
+export AZURE_ENDPOINT="Endpoint=sb://$AZURE_HOST/;SharedAccessKeyName=$AZURE_KEY_NAME;SharedAccessKey=$AZURE_KEY;EntityPath=$AZURE_NAME"
+
+# --- Create/Start omazureeventhubs sender config
+
+generate_conf
+add_conf '
+global(
+ debug.whitelist="on"
+ debug.files=["omazureeventhubs.c", "modules.c", "errmsg.c", "action.c"]
+)
+
+# impstats in order to gain insight into error cases
+module(load="../plugins/impstats/.libs/impstats"
+ log.file="'$RSYSLOG_DYNNAME.pstats'"
+ interval="1" log.syslog="off")
+$imdiagInjectDelayMode full
+
+# Load mods
+module(load="../plugins/omazureeventhubs/.libs/omazureeventhubs")
+
+# templates
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+local4.* {
+ action( name="omazureeventhubs"
+ type="omazureeventhubs"
+ azurehost="'$AZURE_HOST'"
+ azureport="'$AZURE_PORT'"
+ azure_key_name="'$AZURE_KEY_NAME'"
+ azure_key="'$AZURE_KEY'"
+ container="'$AZURE_CONTAINER'"
+# amqp_address="amqps://'$AZURE_KEY_NAME':'$AZURE_KEY'@'$AZURE_HOST'/'$AZURE_NAME'"
+ template="outfmt"
+ action.resumeInterval="1"
+ action.resumeRetryCount="2"
+ )
+
+ action( type="omfile" file="'$RSYSLOG_OUT_LOG'")
+ stop
+}
+
+action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'")
+'
+echo Starting sender instance [omazureeventhubs]
+startup
+
+echo Inject messages into rsyslog sender instance
+injectmsg 1 $NUMMESSAGES
+
+wait_file_lines $RSYSLOG_OUT_LOG $NUMMESSAGESFULL 100
+
+# experimental: wait until kafkacat receives everything
+timeoutend=$WAITTIMEOUT
+timecounter=0
+
+echo "CHECK $RSYSLOG_DYNNAME.pstats"
+while [ $timecounter -lt $timeoutend ]; do
+ (( timecounter++ ))
+
+ if [ -f "$RSYSLOG_DYNNAME.pstats" ] ; then
+ # Read IMPSTATS for verification
+ IMPSTATSLINE=$(cat $RSYSLOG_DYNNAME.pstats | grep "origin\=omazureeventhubs" | tail -1 | cut -d: -f5)
+ SUBMITTED_MSG=$(echo $IMPSTATSLINE | grep "submitted" | cut -d" " -f2 | cut -d"=" -f2)
+ FAILED_MSG=$(echo $IMPSTATSLINE | grep "failures" | cut -d" " -f3 | cut -d"=" -f2)
+ ACCEPTED_MSG=$(echo $IMPSTATSLINE | grep "accepted" | cut -d" " -f4 | cut -d"=" -f2)
+
+ if ! [[ $SUBMITTED_MSG =~ $re ]] ; then
+ echo "**** omazureeventhubs WAITING FOR IMPSTATS"
+ else
+ if [ "$SUBMITTED_MSG" -ge "$NUMMESSAGESFULL" ]; then
+ if [ "$ACCEPTED_MSG" -eq "$NUMMESSAGESFULL" ]; then
+ echo "**** omazureeventhubs SUCCESS: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG"
+ shutdown_when_empty
+ wait_shutdown
+ #cp $RSYSLOG_DEBUGLOG DEBUGDEBUG.log
+ exit_test
+ else
+ echo "**** omazureeventhubs FAIL: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED/WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG"
+ fi
+ else
+ echo "**** omazureeventhubs WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG"
+ fi
+ fi
+ fi
+
+ $TESTTOOL_DIR/msleep 1000
+done
+unset count
+
+shutdown_when_empty
+wait_shutdown
+error_exit 1
diff --git a/tests/omazureeventhubs-interrupt-vg.sh b/tests/omazureeventhubs-interrupt-vg.sh
new file mode 100755
index 0000000..be9fefa
--- /dev/null
+++ b/tests/omazureeventhubs-interrupt-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes --leak-check=full"
+export EXTRA_VALGRIND_SUPPRESSIONS="--suppressions=omazureeventhubs.supp"
+source ${srcdir:-.}/omazureeventhubs-interrupt.sh
diff --git a/tests/omazureeventhubs-interrupt.sh b/tests/omazureeventhubs-interrupt.sh
new file mode 100755
index 0000000..6d92500
--- /dev/null
+++ b/tests/omazureeventhubs-interrupt.sh
@@ -0,0 +1,165 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+echo This test must be run as root [raw socket access required]
+if [ "$EUID" -ne 0 ]; then
+ exit 77 # Not root, skip this test
+fi
+. ${srcdir:=.}/diag.sh init
+
+# --- If test is needed, create helper script to store environment variables for
+# éventhubs access:
+# export AZURE_HOST=""
+# export AZURE_PORT=""
+# export AZURE_KEY_NAME=""
+# export AZURE_KEY=""
+# export AZURE_CONTAINER=""
+# ---
+source omazureeventhubs-env.sh
+
+export NUMMESSAGES=10000
+export NUMMESSAGESFULL=$NUMMESSAGES
+export WAITTIMEOUT=60
+
+export QUEUESIZE=100000
+export DEQUEUESIZE=64
+export DEQUEUESIZEMIN=32
+export TESTWORKERTHREADS=3
+
+export interrupt_host="$AZURE_HOST"
+export interrupt_port="$AZURE_PORT"
+export interrupt_tick="10"
+
+
+# REQUIRES EXTERNAL ENVIRONMENT VARIABLES
+if [[ -z "${AZURE_HOST}" ]]; then
+ echo "SKIP: AZURE_HOST environment variable not SET! Example: <yourname>.servicebus.windows.net - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_PORT}" ]]; then
+ echo "SKIP: AZURE_PORT environment variable not SET! Example: 5671 - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_KEY_NAME}" ]]; then
+ echo "SKIP: AZURE_KEY_NAME environment variable not SET! Example: <yourkeyname> - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_KEY}" ]]; then
+ echo "SKIP: AZURE_KEY environment variable not SET! Example: <yourlongkey> - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_CONTAINER}" ]]; then
+ echo "SKIP: AZURE_CONTAINER environment variable not SET! Example: <youreventhubsname> - SKIPPING"
+ exit 77
+fi
+
+export AMQPS_ADRESS="amqps://$AZURE_KEY_NAME:$AZURE_KEY@$AZURE_HOST:$AZURE_PORT/$AZURE_NAME"
+export AZURE_ENDPOINT="Endpoint=sb://$AZURE_HOST/;SharedAccessKeyName=$AZURE_KEY_NAME;SharedAccessKey=$AZURE_KEY;EntityPath=$AZURE_NAME"
+
+# --- Create/Start omazureeventhubs sender config
+
+generate_conf
+add_conf '
+global(
+# debug.whitelist="on"
+# debug.files=["omazureeventhubs.c", "modules.c", "errmsg.c", "action.c", "queue.c", "ruleset.c"]
+)
+
+# impstats in order to gain insight into error cases
+module(load="../plugins/impstats/.libs/impstats"
+ log.file="'$RSYSLOG_DYNNAME.pstats'"
+ interval="1" log.syslog="off")
+$imdiagInjectDelayMode full
+
+# Load mods
+module(load="../plugins/omazureeventhubs/.libs/omazureeventhubs")
+
+# templates
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+local4.* {
+ action( name="omazureeventhubs"
+ type="omazureeventhubs"
+ azurehost="'$AZURE_HOST'"
+ azureport="'$AZURE_PORT'"
+ azure_key_name="'$AZURE_KEY_NAME'"
+ azure_key="'$AZURE_KEY'"
+ container="'$AZURE_CONTAINER'"
+# amqp_address="amqps://'$AZURE_KEY_NAME':'$AZURE_KEY'@'$AZURE_HOST'/'$AZURE_NAME'"
+ template="outfmt"
+ queue.type="FixedArray"
+ queue.size="'$QUEUESIZE'"
+ queue.saveonshutdown="on"
+ queue.dequeueBatchSize="'$DEQUEUESIZE'"
+ queue.minDequeueBatchSize="'$DEQUEUESIZEMIN'"
+ queue.minDequeueBatchSize.timeout="1000" # 1 sec
+ queue.workerThreads="'$TESTWORKERTHREADS'"
+ queue.workerThreadMinimumMessages="'$DEQUEUESIZEMIN'"
+ queue.timeoutWorkerthreadShutdown="60000"
+ queue.timeoutEnqueue="2000"
+ queue.timeoutshutdown="1000"
+ action.resumeInterval="1"
+ action.resumeRetryCount="2"
+ )
+
+ action( type="omfile" file="'$RSYSLOG_OUT_LOG'")
+ stop
+}
+
+action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'")
+'
+echo Starting sender instance [omazureeventhubs]
+startup
+
+echo Inject messages into rsyslog sender instance
+injectmsg 1 $NUMMESSAGES
+
+wait_file_lines --interrupt-connection $interrupt_host $interrupt_port $interrupt_tick $RSYSLOG_OUT_LOG $NUMMESSAGESFULL 100
+
+timeoutend=$WAITTIMEOUT
+timecounter=0
+lastcurrent_time=0
+
+echo "CHECK $RSYSLOG_DYNNAME.pstats"
+while [ $timecounter -lt $timeoutend ]; do
+ (( timecounter++ ))
+
+ if [ -f "$RSYSLOG_DYNNAME.pstats" ] ; then
+ # Read IMPSTATS for verification
+ IMPSTATSLINE=$(cat $RSYSLOG_DYNNAME.pstats | grep "origin\=omazureeventhubs" | tail -1 | cut -d: -f5)
+ SUBMITTED_MSG=$(echo $IMPSTATSLINE | grep "submitted" | cut -d" " -f2 | cut -d"=" -f2)
+ FAILED_MSG=$(echo $IMPSTATSLINE | grep "failures" | cut -d" " -f3 | cut -d"=" -f2)
+ ACCEPTED_MSG=$(echo $IMPSTATSLINE | grep "accepted" | cut -d" " -f4 | cut -d"=" -f2)
+
+ if ! [[ $SUBMITTED_MSG =~ $re ]] ; then
+ echo "**** omazureeventhubs WAITING FOR IMPSTATS"
+ else
+ if [ "$SUBMITTED_MSG" -ge "$NUMMESSAGESFULL" ]; then
+ if [ "$ACCEPTED_MSG" -ge "$NUMMESSAGESFULL" ]; then
+ echo "**** omazureeventhubs SUCCESS: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG"
+ shutdown_when_empty
+ wait_shutdown
+ #cp $RSYSLOG_DEBUGLOG DEBUGDEBUG.log
+ exit_test
+ else
+ echo "**** omazureeventhubs FAIL: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED/WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG"
+ fi
+ else
+ echo "**** omazureeventhubs WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG"
+ current_time=$(date +%s)
+ if [ $interrupt_connection == "YES" ] && [ $current_time -gt $lastcurrent_time ] && [ $((current_time % $interrupt_tick)) -eq 0 ] && [ ${count} -gt 1 ]; then
+ # Interrupt Connection - requires root and linux kernel >= 4.9 in order to work!
+ echo "**** omazureeventhubs WAITING: Interrupt Connection on ${interrupt_host}:${interrupt_port}"
+ sudo ss -K dst ${interrupt_host} dport = ${interrupt_port}
+ fi
+ lastcurrent_time=$current_time
+ fi
+ fi
+ fi
+
+ $TESTTOOL_DIR/msleep 1000
+done
+unset count
+
+shutdown_when_empty
+wait_shutdown
+error_exit 1
diff --git a/tests/omazureeventhubs-list.sh b/tests/omazureeventhubs-list.sh
new file mode 100755
index 0000000..01f3b01
--- /dev/null
+++ b/tests/omazureeventhubs-list.sh
@@ -0,0 +1,137 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=100
+export NUMMESSAGESFULL=$NUMMESSAGES
+export WAITTIMEOUT=20
+
+# REQUIRES EXTERNAL ENVIRONMENT VARIABLES
+if [[ -z "${AZURE_HOST}" ]]; then
+ echo "SKIP: AZURE_HOST environment variable not SET! Example: <yourname>.servicebus.windows.net - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_PORT}" ]]; then
+ echo "SKIP: AZURE_PORT environment variable not SET! Example: 5671 - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_KEY_NAME}" ]]; then
+ echo "SKIP: AZURE_KEY_NAME environment variable not SET! Example: <yourkeyname> - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_KEY}" ]]; then
+ echo "SKIP: AZURE_KEY environment variable not SET! Example: <yourlongkey> - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_CONTAINER}" ]]; then
+ echo "SKIP: AZURE_CONTAINER environment variable not SET! Example: <youreventhubsname> - SKIPPING"
+ exit 77
+fi
+
+export AMQPS_ADRESS="amqps://$AZURE_KEY_NAME:$AZURE_KEY@$AZURE_HOST:$AZURE_PORT/$AZURE_NAME"
+export AZURE_ENDPOINT="Endpoint=sb://$AZURE_HOST/;SharedAccessKeyName=$AZURE_KEY_NAME;SharedAccessKey=$AZURE_KEY;EntityPath=$AZURE_NAME"
+
+# --- Create/Start omazureeventhubs sender config
+generate_conf
+add_conf '
+# impstats in order to gain insight into error cases
+module(load="../plugins/impstats/.libs/impstats"
+ log.file="'$RSYSLOG_DYNNAME.pstats'"
+ interval="1" log.syslog="off")
+$imdiagInjectDelayMode full
+
+# Load mods
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omazureeventhubs/.libs/omazureeventhubs")
+
+# imtcp
+input( type="imtcp"
+ port="0"
+ ruleset="default"
+ listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# templates
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+template(name="generic" type="list" option.jsonf="on") {
+ property(outname="timestamp" name="timereported" dateFormat="rfc3339" format="jsonf")
+ constant(value="\"source\": \"EventHubMessage\", ")
+ property(outname="host" name="hostname" format="jsonf")
+ property(outname="severity" name="syslogseverity" caseConversion="upper" format="jsonf" datatype="number")
+ property(outname="facility" name="syslogfacility" format="jsonf" datatype="number")
+ property(outname="appname" name="syslogtag" format="jsonf")
+ property(outname="message" name="msg" format="jsonf" )
+ property(outname="etlsource" name="$myhostname" format="jsonf")}
+
+# ruleset
+ruleset(name="default") {
+ if $msg contains "msgnum:" then {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+ action(type="omfile" template="generic" file="'$RSYSLOG_OUT_LOG'-generic.log")
+ action(name="omazureeventhubs"
+ type="omazureeventhubs"
+ azurehost="'$AZURE_HOST'"
+ azureport="'$AZURE_PORT'"
+ azure_key_name="'$AZURE_KEY_NAME'"
+ azure_key="'$AZURE_KEY'"
+ container="'$AZURE_CONTAINER'"
+ template="generic"
+ eventproperties=[ "Table=TestTable",
+ "Format=JSON"]
+ )
+ } else {
+ action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'")
+ }
+ stop
+}
+
+'
+echo Starting sender instance [omazureeventhubs]
+startup
+
+echo Inject messages into rsyslog sender instance
+# injectmsg 1 $NUMMESSAGES
+tcpflood -m$NUMMESSAGES -i1
+
+wait_file_lines $RSYSLOG_OUT_LOG $NUMMESSAGESFULL 100
+
+# experimental: wait until kafkacat receives everything
+timeoutend=$WAITTIMEOUT
+timecounter=0
+
+echo "CHECK $RSYSLOG_DYNNAME.pstats"
+while [ $timecounter -lt $timeoutend ]; do
+ (( timecounter++ ))
+
+ if [ -f "$RSYSLOG_DYNNAME.pstats" ] ; then
+ # Read IMPSTATS for verification
+ IMPSTATSLINE=$(cat $RSYSLOG_DYNNAME.pstats | grep "origin\=omazureeventhubs" | tail -1 | cut -d: -f5)
+ SUBMITTED_MSG=$(echo $IMPSTATSLINE | grep "submitted" | cut -d" " -f2 | cut -d"=" -f2)
+ FAILED_MSG=$(echo $IMPSTATSLINE | grep "failures" | cut -d" " -f3 | cut -d"=" -f2)
+ ACCEPTED_MSG=$(echo $IMPSTATSLINE | grep "accepted" | cut -d" " -f4 | cut -d"=" -f2)
+
+ if ! [[ $SUBMITTED_MSG =~ $re ]] ; then
+ echo "**** omazureeventhubs WAITING FOR IMPSTATS"
+ else
+ if [ "$SUBMITTED_MSG" -ge "$NUMMESSAGESFULL" ]; then
+ if [ "$ACCEPTED_MSG" -eq "$NUMMESSAGESFULL" ]; then
+ echo "**** omazureeventhubs SUCCESS: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG"
+ shutdown_when_empty
+ wait_shutdown
+ #cp $RSYSLOG_DEBUGLOG DEBUGDEBUG.log
+ exit_test
+ else
+ echo "**** omazureeventhubs FAIL: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED/WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG"
+ fi
+ else
+ echo "**** omazureeventhubs WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG"
+ fi
+ fi
+ fi
+
+ $TESTTOOL_DIR/msleep 1000
+done
+unset count
+
+shutdown_when_empty
+wait_shutdown
+error_exit 1
diff --git a/tests/omazureeventhubs-stress.sh b/tests/omazureeventhubs-stress.sh
new file mode 100755
index 0000000..2587b0a
--- /dev/null
+++ b/tests/omazureeventhubs-stress.sh
@@ -0,0 +1,137 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=50000
+export NUMMESSAGESFULL=$NUMMESSAGES
+export WAITTIMEOUT=60
+
+export QUEUESIZE=100000
+export DEQUEUESIZE=1000
+export DEQUEUESIZEMIN=1000
+export TESTWORKERTHREADS=10
+
+# REQUIRES EXTERNAL ENVIRONMENT VARIABLES
+if [[ -z "${AZURE_HOST}" ]]; then
+ echo "SKIP: AZURE_HOST environment variable not SET! Example: <yourname>.servicebus.windows.net - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_PORT}" ]]; then
+ echo "SKIP: AZURE_PORT environment variable not SET! Example: 5671 - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_KEY_NAME}" ]]; then
+ echo "SKIP: AZURE_KEY_NAME environment variable not SET! Example: <yourkeyname> - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_KEY}" ]]; then
+ echo "SKIP: AZURE_KEY environment variable not SET! Example: <yourlongkey> - SKIPPING"
+ exit 77
+fi
+if [[ -z "${AZURE_CONTAINER}" ]]; then
+ echo "SKIP: AZURE_CONTAINER environment variable not SET! Example: <youreventhubsname> - SKIPPING"
+ exit 77
+fi
+
+export AMQPS_ADRESS="amqps://$AZURE_KEY_NAME:$AZURE_KEY@$AZURE_HOST:$AZURE_PORT/$AZURE_NAME"
+export AZURE_ENDPOINT="Endpoint=sb://$AZURE_HOST/;SharedAccessKeyName=$AZURE_KEY_NAME;SharedAccessKey=$AZURE_KEY;EntityPath=$AZURE_NAME"
+
+# --- Create/Start omazureeventhubs sender config
+
+generate_conf
+add_conf '
+global(
+ debug.whitelist="on"
+ debug.files=["omazureeventhubs.c", "modules.c", "errmsg.c", "action.c"]
+)
+# impstats in order to gain insight into error cases
+module(load="../plugins/impstats/.libs/impstats"
+ log.file="'$RSYSLOG_DYNNAME.pstats'"
+ interval="1" log.syslog="off")
+$imdiagInjectDelayMode full
+
+# main_queue(queue.dequeueBatchSize="2048")
+
+# Load mods
+module(load="../plugins/omazureeventhubs/.libs/omazureeventhubs")
+
+# templates
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+local4.* {
+ action( name="omazureeventhubs"
+ type="omazureeventhubs"
+ azurehost="'$AZURE_HOST'"
+ azureport="'$AZURE_PORT'"
+ azure_key_name="'$AZURE_KEY_NAME'"
+ azure_key="'$AZURE_KEY'"
+ container="'$AZURE_CONTAINER'"
+ template="outfmt"
+ queue.type="FixedArray"
+ queue.size="'$QUEUESIZE'"
+ queue.saveonshutdown="on"
+ queue.dequeueBatchSize="'$DEQUEUESIZE'"
+ queue.minDequeueBatchSize.timeout="1000" # 1 sec
+ queue.workerThreads="'$TESTWORKERTHREADS'"
+ queue.workerThreadMinimumMessages="'$DEQUEUESIZEMIN'"
+ queue.timeoutWorkerthreadShutdown="10000"
+ queue.timeoutshutdown="1000"
+ action.resumeInterval="1"
+ action.resumeRetryCount="2"
+ )
+
+ stop
+}
+
+action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'")
+'
+echo Starting sender instance [omazureeventhubs]
+startup
+
+echo Inject messages into rsyslog sender instance
+injectmsg 1 $NUMMESSAGES
+
+# experimental: wait until kafkacat receives everything
+timeoutend=$WAITTIMEOUT
+timecounter=0
+
+echo "CHECK $RSYSLOG_DYNNAME.pstats"
+LAST_ACCEPTED_MSG=0
+while [ $timecounter -lt $timeoutend ]; do
+ (( timecounter++ ))
+
+ if [ -f "$RSYSLOG_DYNNAME.pstats" ] ; then
+ # Read IMPSTATS for verification
+ IMPSTATSLINE=$(cat $RSYSLOG_DYNNAME.pstats | grep "origin\=omazureeventhubs" | tail -1 | cut -d: -f5)
+ SUBMITTED_MSG=$(echo $IMPSTATSLINE | grep "submitted" | cut -d" " -f2 | cut -d"=" -f2)
+ FAILED_MSG=$(echo $IMPSTATSLINE | grep "failures" | cut -d" " -f3 | cut -d"=" -f2)
+ ACCEPTED_MSG=$(echo $IMPSTATSLINE | grep "accepted" | cut -d" " -f4 | cut -d"=" -f2)
+ MSG_PER_SEC=$(($ACCEPTED_MSG-$LAST_ACCEPTED_MSG))
+ LAST_ACCEPTED_MSG=$ACCEPTED_MSG
+
+ if ! [[ $SUBMITTED_MSG =~ $re ]] ; then
+ echo "**** omazureeventhubs WAITING FOR IMPSTATS"
+ else
+ if [ "$SUBMITTED_MSG" -ge "$NUMMESSAGESFULL" ]; then
+ if [ "$ACCEPTED_MSG" -ge "$NUMMESSAGESFULL" ]; then
+ echo "**** omazureeventhubs SUCCESS: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG"
+ shutdown_when_empty
+ wait_shutdown
+ #cp $RSYSLOG_DEBUGLOG DEBUGDEBUG.log
+ exit_test
+ else
+ echo "**** omazureeventhubs FAIL: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED/WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG"
+ fi
+ else
+ echo "**** omazureeventhubs WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG, MSG_PER_SEC: $MSG_PER_SEC"
+ fi
+ fi
+ fi
+
+ $TESTTOOL_DIR/msleep 1000
+done
+unset count
+
+shutdown_when_empty
+wait_shutdown
+error_exit 1
diff --git a/tests/omfile-module-params.sh b/tests/omfile-module-params.sh
new file mode 100755
index 0000000..1f4e5b8
--- /dev/null
+++ b/tests/omfile-module-params.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# addd 2018-08-02 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=100 # we only check output fmt, so few messages are OK
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="builtin:omfile" template="outfmt")
+
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/omfile-null-filename.sh b/tests/omfile-null-filename.sh
new file mode 100755
index 0000000..10f323e
--- /dev/null
+++ b/tests/omfile-null-filename.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# check that omfile does not segfault when filename is given but empty.
+# addd 2018-04-03 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+action(type="omfile" file="")
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+grep "parameter must be given" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/omfile-outchannel-many.sh b/tests/omfile-outchannel-many.sh
new file mode 100755
index 0000000..102f1eb
--- /dev/null
+++ b/tests/omfile-outchannel-many.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+# addd 2018-08-02 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=500000
+echo "ls -l $RSYSLOG_DYNNAME.channel.*
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.9 $RSYSLOG_DYNNAME.channel.log.prev.10 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.8 $RSYSLOG_DYNNAME.channel.log.prev.9 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.7 $RSYSLOG_DYNNAME.channel.log.prev.8 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.6 $RSYSLOG_DYNNAME.channel.log.prev.7 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.5 $RSYSLOG_DYNNAME.channel.log.prev.6 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.4 $RSYSLOG_DYNNAME.channel.log.prev.5 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.3 $RSYSLOG_DYNNAME.channel.log.prev.4 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.2 $RSYSLOG_DYNNAME.channel.log.prev.3 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.1 $RSYSLOG_DYNNAME.channel.log.prev.2 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev $RSYSLOG_DYNNAME.channel.log.prev.1 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log $RSYSLOG_DYNNAME.channel.log.prev
+" > $RSYSLOG_DYNNAME.rotate.sh
+chmod +x $RSYSLOG_DYNNAME.rotate.sh
+generate_conf
+add_conf '
+main_queue(
+ queue.workerthreads="4"
+ queue.timeoutWorkerthreadShutdown="-1"
+ queue.workerThreadMinimumMessages="10"
+)
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="tcp")
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+module(load="builtin:omfile" template="outfmt")
+$outchannel log_rotation,'$RSYSLOG_DYNNAME.channel.log', $NUMMESSAGES,./'$RSYSLOG_DYNNAME.rotate.sh'
+
+if $msg contains "msgnum:" then {
+# if $/num % 2 == 0 then
+ :omfile:$log_rotation
+# else
+# :omfile:$log_rotation2
+# set $/num = $/num + 1;
+}
+
+ruleset(name="tcp") {
+ :omfile:$log_rotation2
+}
+'
+startup
+./tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES & # TCPFlood needs to run async!
+#./msleep 2500
+injectmsg
+sleep 1
+shutdown_when_empty
+wait_shutdown
+ls -l $RSYSLOG_DYNNAME.channel.*
+cat $RSYSLOG_DYNNAME.channel.* > $RSYSLOG_OUT_LOG
+seq_check
+exit_test
diff --git a/tests/omfile-outchannel.sh b/tests/omfile-outchannel.sh
new file mode 100755
index 0000000..329f844
--- /dev/null
+++ b/tests/omfile-outchannel.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# addd 2018-08-02 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10000
+echo "ls -l $RSYSLOG_DYNNAME*
+mv -f $RSYSLOG_DYNNAME.channel.log $RSYSLOG_DYNNAME.channel.log.prev
+" > $RSYSLOG_DYNNAME.rotate.sh
+chmod +x $RSYSLOG_DYNNAME.rotate.sh
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+module(load="builtin:omfile" template="outfmt")
+$outchannel log_rotation,'$RSYSLOG_DYNNAME.channel.log', 50000,./'$RSYSLOG_DYNNAME.rotate.sh'
+:msg, contains, "msgnum:" :omfile:$log_rotation
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+cat $RSYSLOG_DYNNAME.channel.* > $RSYSLOG_OUT_LOG
+ls -l $RSYSLOG_DYNNAME*
+seq_check
+exit_test
diff --git a/tests/omfile-read-only-errmsg.sh b/tests/omfile-read-only-errmsg.sh
new file mode 100755
index 0000000..da1bd4f
--- /dev/null
+++ b/tests/omfile-read-only-errmsg.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# addd 2017-03-01 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" {
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG2_OUT_LOG`)
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+touch ${RSYSLOG2_OUT_LOG}
+chmod 0400 ${RSYSLOG2_OUT_LOG}
+ls -l rsyslog.ou*
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+
+grep "${RSYSLOG2_OUT_LOG}.* open error" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/omfile-read-only.sh b/tests/omfile-read-only.sh
new file mode 100755
index 0000000..7cc25d1
--- /dev/null
+++ b/tests/omfile-read-only.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# addd 2016-06-16 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+messages=20000 # how many messages to inject?
+# Note: we need to inject a somewhat larger number of messages in order
+# to ensure that we receive some messages in the actual output file,
+# as batching can (validly) cause a larger loss in the non-writable
+# file
+
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG2_OUT_LOG'")
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'"
+ action.execOnlyWhenPreviousIsSuspended="on"
+ )
+}
+'
+touch ${RSYSLOG2_OUT_LOG}
+chmod 0400 ${RSYSLOG2_OUT_LOG}
+ls -l rsyslog.ou*
+startup
+injectmsg 0 $messages
+shutdown_when_empty
+wait_shutdown
+# we know that the output file is missing some messages, but it
+# MUST have some more, and these be in sequence. So we now read
+# the first message number and calculate based on it what must be
+# present in the output file.
+presort
+let firstnum=$((10#$($RS_HEADCMD -n1 $RSYSLOG_DYNNAME.presort)))
+echo "info: first message expected to be number $firstnum, using that value."
+seq_check $firstnum $((messages-1))
+exit_test
diff --git a/tests/omfile-sizelimitcmd-many.sh b/tests/omfile-sizelimitcmd-many.sh
new file mode 100755
index 0000000..b1c8d0b
--- /dev/null
+++ b/tests/omfile-sizelimitcmd-many.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# addd 2023-01-11 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+echo "ls -l $RSYSLOG_DYNNAME.channel.*
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.9 $RSYSLOG_DYNNAME.channel.log.prev.10 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.8 $RSYSLOG_DYNNAME.channel.log.prev.9 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.7 $RSYSLOG_DYNNAME.channel.log.prev.8 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.6 $RSYSLOG_DYNNAME.channel.log.prev.7 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.5 $RSYSLOG_DYNNAME.channel.log.prev.6 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.4 $RSYSLOG_DYNNAME.channel.log.prev.5 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.3 $RSYSLOG_DYNNAME.channel.log.prev.4 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.2 $RSYSLOG_DYNNAME.channel.log.prev.3 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev.1 $RSYSLOG_DYNNAME.channel.log.prev.2 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log.prev $RSYSLOG_DYNNAME.channel.log.prev.1 2>/dev/null
+mv -f $RSYSLOG_DYNNAME.channel.log $RSYSLOG_DYNNAME.channel.log.prev
+" > $RSYSLOG_DYNNAME.rotate.sh
+chmod +x $RSYSLOG_DYNNAME.rotate.sh
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum:" then {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME.channel.log'" template="outfmt"
+ rotation.sizeLimit="50k"
+ rotation.sizeLimitCommand="./'$RSYSLOG_DYNNAME.rotate.sh'")
+}
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+ls -l $RSYSLOG_DYNNAME.channel.*
+cat $RSYSLOG_DYNNAME.channel.* > $RSYSLOG_OUT_LOG
+seq_check
+exit_test
diff --git a/tests/omfile-whitespace-filename.sh b/tests/omfile-whitespace-filename.sh
new file mode 100755
index 0000000..7396382
--- /dev/null
+++ b/tests/omfile-whitespace-filename.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# addd 2018-04-03 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+action(type="omfile" file=" ")
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+grep "only of whitespace" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/omfile_both_files_set.sh b/tests/omfile_both_files_set.sh
new file mode 100755
index 0000000..83bef8b
--- /dev/null
+++ b/tests/omfile_both_files_set.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="dynafile" type="string" string=`echo $RSYSLOG_OUT_LOG`)
+template(name="outfmt" type="string" string="-%msg%-\n")
+
+:msg, contains, "msgnum:" {
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG2_OUT_LOG` dynafile="dynafile")
+}
+action(type="omfile" file="'${RSYSLOG_DYNNAME}'.errorfile")
+'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\""
+shutdown_when_empty
+wait_shutdown
+
+grep "will use dynafile" ${RSYSLOG_DYNNAME}.errorfile > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message not found. ${RSYSLOG_DYNNAME}.errorfile is:"
+ cat ${RSYSLOG_DYNNAME}.errorfile
+ error_exit 1
+fi
+
+echo '- msgnum:1-' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "unexpected content in $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+if [ -f ${RSYSLOG2_OUT_LOG} ]; then
+ echo "file exists, but should not: ${RSYSLOG2_OUT_LOG}; content:"
+ cat ${RSYSLOG2_OUT_LOG}
+ error_exit 1
+fi;
+
+
+exit_test
diff --git a/tests/omfile_hup-vg.sh b/tests/omfile_hup-vg.sh
new file mode 100755
index 0000000..a41e5c4
--- /dev/null
+++ b/tests/omfile_hup-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export NUMMESSAGES=200000 # reduce for slower valgrind run
+source ${srcdir:-.}/omfile_hup.sh
diff --git a/tests/omfile_hup.sh b/tests/omfile_hup.sh
new file mode 100755
index 0000000..6dc28e1
--- /dev/null
+++ b/tests/omfile_hup.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# Written 2019-06-21 by Rainer Gerhards
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=${NUMMESSAGES:-1000000}
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'")
+
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt" dynafile="dynfile")
+'
+startup
+./tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES & # TCPFlood needs to run async!
+BGPROCESS=$!
+for i in $(seq 1 20); do
+ printf '\nsending HUP %d\n' $i
+ issue_HUP --sleep 100
+done
+wait $BGPROCESS
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/omfwd-errfile-maxsize-filled.sh b/tests/omfwd-errfile-maxsize-filled.sh
new file mode 100755
index 0000000..25a08ec
--- /dev/null
+++ b/tests/omfwd-errfile-maxsize-filled.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+ERRFILE="$RSYSLOG_DYNNAME.err"
+export MAX_ERROR_SIZE=1999
+export INITIAL_FILE_SIZE=$((MAX_ERROR_SIZE - 100))
+dd if=/dev/urandom of=${ERRFILE} bs=1 count=${INITIAL_FILE_SIZE}
+generate_conf
+add_conf '
+action(type="omfwd" target="1.2.3.4" port="1234" Protocol="tcp" NetworkNamespace="doesNotExist"
+ action.errorfile="'$ERRFILE'" action.errorfile.maxsize="'$MAX_ERROR_SIZE'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+check_file_exists ${ERRFILE}
+file_size_check ${ERRFILE} ${MAX_ERROR_SIZE}
+exit_test
diff --git a/tests/omfwd-errfile-maxsize.sh b/tests/omfwd-errfile-maxsize.sh
new file mode 100755
index 0000000..91756a8
--- /dev/null
+++ b/tests/omfwd-errfile-maxsize.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+export MAX_ERROR_SIZE=1999
+
+generate_conf
+add_conf '
+action(type="omfwd" target="1.2.3.4" port="1234" Protocol="tcp" NetworkNamespace="doesNotExist"
+ action.errorfile="'$RSYSLOG2_OUT_LOG'" action.errorfile.maxsize="'$MAX_ERROR_SIZE'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+check_file_exists ${RSYSLOG2_OUT_LOG}
+file_size_check ${RSYSLOG2_OUT_LOG} ${MAX_ERROR_SIZE}
+exit_test
diff --git a/tests/omfwd-keepalive.sh b/tests/omfwd-keepalive.sh
new file mode 100755
index 0000000..32b30fa
--- /dev/null
+++ b/tests/omfwd-keepalive.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# addd 2016-03-30 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="list") {
+ property(name="msg")
+ constant(value="\n")
+}
+:msg, contains, "x-pid" stop
+
+
+if $msg contains "msgnum:" then
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+
+:msg, contains, "this does not occur" action(type="omfwd"
+ target="10.0.0.1" keepalive="on" keepalive.probes="10"
+ keepalive.time="60" keepalive.interval="10")
+
+'
+startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo " msgnum:00000000:" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid output generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/omfwd-tls-invalid-permitExpiredCerts.sh b/tests/omfwd-tls-invalid-permitExpiredCerts.sh
new file mode 100755
index 0000000..da845fc
--- /dev/null
+++ b/tests/omfwd-tls-invalid-permitExpiredCerts.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# add 2020-01-08 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+action(type="omfwd" target="localhost" port="514" streamdriver.permitexpiredcerts="invld")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "streamdriver.permitExpiredCerts must be 'warn', 'off' or 'on' but is 'invld'"
+exit_test
diff --git a/tests/omfwd_fast_imuxsock.sh b/tests/omfwd_fast_imuxsock.sh
new file mode 100755
index 0000000..10f9f19
--- /dev/null
+++ b/tests/omfwd_fast_imuxsock.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+# This test tries tests DiscardMark / DiscardSeverity queue settings with omfwd with IMUXSOCK input
+# added 2021-09-02 by alorbach. Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "We have no ATOMIC BUILTINS, so OverallQueueSize counting of imdiag is NOT threadsafe and the counting will fail on SunOS"
+
+./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1
+no_liblogging_stdlog=$?
+if [ $no_liblogging_stdlog -ne 0 ];then
+ echo "liblogging-stdlog not available - skipping test"
+ exit 77
+fi
+
+# export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+export NUMMESSAGES=100000
+
+export PORT_RCVR="$(get_free_port)"
+export STATSFILE="$RSYSLOG_DYNNAME.stats"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog"
+generate_conf
+add_conf '
+global( debug.whitelist="on"
+ debug.files=["imdiag.c", "queue.c"]
+)
+
+template(name="testformat" type="list") {
+ constant(value="{ ")
+ property(name="timereported" dateFormat="unixtimestamp" format="jsonf")
+ constant(value=", ")
+ property(name="syslogseverity-text" format="jsonf")
+ constant(value=", ")
+ property(name="programname" format="jsonf")
+ constant(value=", ")
+ property(name="msg" format="jsonf")
+ constant(value=" }\n")
+}
+template(name="outfmt"
+ type="string"
+ string="%msg:F,58:2%\n")
+
+# IMUX Input socket
+module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off")
+input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket")
+
+# Note: stats module
+module(load="../plugins/impstats/.libs/impstats" log.file="'$STATSFILE'" interval="1" ruleset="stats")
+
+main_queue(
+ queue.timeoutshutdown="10000"
+# queue.timeoutEnqueue="20"
+# queue.discardSeverity="3"
+)
+
+ruleset(name="stats") {
+ stop # nothing to do here
+}
+
+if $msg contains "test message nbr" then
+ action(
+ type="omfwd"
+ Target="127.0.0.1"
+ Port="'$PORT_RCVR'"
+ Protocol="tcp"
+ TCP_Framing="octet-counted"
+ ResendLastMSGOnReconnect="on"
+
+ Template="testformat"
+
+ queue.discardMark="100"
+ queue.discardSeverity="3"
+
+# queue.timeoutEnqueue="5"
+ queue.type="linkedlist"
+ )
+'
+./minitcpsrv -t127.0.0.1 -p$PORT_RCVR -f $RSYSLOG_OUT_LOG &
+BGPROCESS=$!
+echo background tcp dummy receiver process id is $BGPROCESS
+
+# now do the usual run
+startup
+
+# Use syslog_caller
+./syslog_caller -m$NUMMESSAGES -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket"
+shutdown_when_empty
+wait_shutdown
+# note: minitcpsrv shuts down automatically if the connection is closed!
+
+# check output file generation, should contain at least 100 logs
+check_file_exists "$RSYSLOG_OUT_LOG"
+check_file_exists "$STATSFILE"
+content_check --regex --output-results "action-1-builtin:omfwd queue: origin=core.queue size=.* enqueued=100000 full=0 discarded.full=0 discarded.nf=.* maxqsize=100" $STATSFILE
+
+exit_test
diff --git a/tests/omfwd_impstats-tcp.sh b/tests/omfwd_impstats-tcp.sh
new file mode 100755
index 0000000..2faae1a
--- /dev/null
+++ b/tests/omfwd_impstats-tcp.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# This test tests impstats omfwd counters in TCP mode
+# added 2021-02-11 by rgerhards. Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+export STATSFILE="$RSYSLOG_DYNNAME.stats"
+add_conf '
+$MainMsgQueueTimeoutShutdown 10000
+
+
+module(load="../plugins/impstats/.libs/impstats" log.file="'$STATSFILE'"
+ interval="1" ruleset="stats")
+
+ruleset(name="stats") {
+ stop # nothing to do here
+}
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+module(load="builtin:omfwd" template="outfmt")
+
+if $msg contains "msgnum:" then
+ action(type="omfwd" target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="tcp")
+'
+./minitcpsrv -t127.0.0.1 -p$TCPFLOOD_PORT -f $RSYSLOG_OUT_LOG &
+BGPROCESS=$!
+echo background minitcpsrv process id is $BGPROCESS
+
+# now do the usual run
+startup
+# 10000 messages should be enough
+injectmsg 0 10000
+shutdown_when_empty
+wait_shutdown
+# note: minitcpsrv shuts down automatically if the connection is closed!
+
+# check pstats - that's our prime test target
+content_check --regex "TCP-.*origin=omfwd .*bytes.sent=[1-9][0-9][0-9]" "$STATSFILE"
+
+# do a bonus test while we are at it (just make sure we actually sent data)
+seq_check 0 9999
+exit_test
diff --git a/tests/omfwd_impstats-udp.sh b/tests/omfwd_impstats-udp.sh
new file mode 100755
index 0000000..56983e6
--- /dev/null
+++ b/tests/omfwd_impstats-udp.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# This test tests impstats omfwd counters in UPD mode
+# added 2021-02-11 by rgerhards. Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+export STATSFILE="$RSYSLOG_DYNNAME.stats"
+add_conf '
+$MainMsgQueueTimeoutShutdown 10000
+
+
+module(load="../plugins/impstats/.libs/impstats" log.file="'$STATSFILE'"
+ interval="1" ruleset="stats")
+
+ruleset(name="stats") {
+ stop # nothing to do here
+}
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+module(load="builtin:omfwd" template="outfmt")
+
+if $msg contains "msgnum:" then
+ action(type="omfwd" target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="udp")
+'
+# note: there must be no actual data - it's fine for this test if all data is lost
+
+# now do the usual run
+startup
+# 10000 messages should be enough
+injectmsg 0 10000
+shutdown_when_empty
+wait_shutdown
+
+# check pstats - that's our prime test target
+content_check --regex "UDP-.*origin=omfwd .*bytes.sent=[1-9][0-9][0-9]" "$STATSFILE"
+exit_test
diff --git a/tests/omhttp-auth-vg.sh b/tests/omhttp-auth-vg.sh
new file mode 100755
index 0000000..8f28dca
--- /dev/null
+++ b/tests/omhttp-auth-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/omhttp-auth.sh
diff --git a/tests/omhttp-auth.sh b/tests/omhttp-auth.sh
new file mode 100755
index 0000000..4a93e4c
--- /dev/null
+++ b/tests/omhttp-auth.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=100
+
+omhttp_start_server 0 --userpwd="bob:bobbackwards"
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../contrib/omhttp/.libs/omhttp")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="off"
+
+ # Auth
+ usehttps="off"
+ uid="bob"
+ pwd="bobbackwards"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-basic-vg.sh b/tests/omhttp-basic-vg.sh
new file mode 100755
index 0000000..0837cb6
--- /dev/null
+++ b/tests/omhttp-basic-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/omhttp-basic.sh
diff --git a/tests/omhttp-basic.sh b/tests/omhttp-basic.sh
new file mode 100755
index 0000000..52ec9c9
--- /dev/null
+++ b/tests/omhttp-basic.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=10000
+
+omhttp_start_server 0
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../contrib/omhttp/.libs/omhttp")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="off"
+
+ # Auth
+ usehttps="off"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-batch-dynrestpath.sh b/tests/omhttp-batch-dynrestpath.sh
new file mode 100755
index 0000000..28fe798
--- /dev/null
+++ b/tests/omhttp-batch-dynrestpath.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=10000
+export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+
+omhttp_start_server 0
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+template(name="dynrestpath" type="string" string="my/endpoint")
+
+module(load="../contrib/omhttp/.libs/omhttp")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ dynrestpath = "on"
+ restpath="dynrestpath"
+
+ batch="on"
+ batch.format="jsonarray"
+ batch.maxsize="1000"
+
+ # Auth
+ usehttps="off"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint jsonarray
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-batch-fail-with-400.sh b/tests/omhttp-batch-fail-with-400.sh
new file mode 100755
index 0000000..7d2347b
--- /dev/null
+++ b/tests/omhttp-batch-fail-with-400.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+omhttp_start_server 0 --fail-with-400-after 1000
+
+generate_conf
+add_conf '
+module(load="../contrib/omhttp/.libs/omhttp")
+
+main_queue(queue.dequeueBatchSize="2048")
+
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+# Wrap message as a single batch for retry
+template(name="tpl_retry" type="string" string="[%msg%]")
+
+
+ruleset(name="ruleset_omhttp") {
+ action(
+ name="action_omhttp"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="off"
+
+ retry="on"
+
+ # Auth
+ usehttps="off"
+ ) & stop
+}
+
+if $msg contains "msgnum:" then
+ call ruleset_omhttp
+'
+startup
+injectmsg 0 10000
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint
+omhttp_stop_server
+seq_check 0 999
+exit_test
diff --git a/tests/omhttp-batch-jsonarray-compress-vg.sh b/tests/omhttp-batch-jsonarray-compress-vg.sh
new file mode 100755
index 0000000..3fdd7fc
--- /dev/null
+++ b/tests/omhttp-batch-jsonarray-compress-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/omhttp-batch-jsonarray-compress.sh
diff --git a/tests/omhttp-batch-jsonarray-compress.sh b/tests/omhttp-batch-jsonarray-compress.sh
new file mode 100755
index 0000000..728ae2e
--- /dev/null
+++ b/tests/omhttp-batch-jsonarray-compress.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=50000
+
+omhttp_start_server 0 --decompress
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../contrib/omhttp/.libs/omhttp")
+
+main_queue(queue.dequeueBatchSize="2048")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="on"
+ batch.format="jsonarray"
+ batch.maxsize="1000"
+ compress="on"
+
+ # Auth
+ usehttps="off"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint jsonarray
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-batch-jsonarray-retry-vg.sh b/tests/omhttp-batch-jsonarray-retry-vg.sh
new file mode 100755
index 0000000..147e16b
--- /dev/null
+++ b/tests/omhttp-batch-jsonarray-retry-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/omhttp-batch-jsonarray-retry.sh
diff --git a/tests/omhttp-batch-jsonarray-retry.sh b/tests/omhttp-batch-jsonarray-retry.sh
new file mode 100755
index 0000000..22e4448
--- /dev/null
+++ b/tests/omhttp-batch-jsonarray-retry.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=50000
+
+omhttp_start_server 0 --fail-every 100
+
+generate_conf
+add_conf '
+module(load="../contrib/omhttp/.libs/omhttp")
+
+main_queue(queue.dequeueBatchSize="2048")
+
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+# Echo message as-is for retry
+template(name="tpl_echo" type="string" string="%msg%")
+
+ruleset(name="ruleset_omhttp_retry") {
+ action(
+ name="action_omhttp"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl_echo"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="on"
+ batch.maxsize="100"
+ batch.format="jsonarray"
+
+ retry="on"
+ retry.ruleset="ruleset_omhttp_retry"
+
+ # Auth
+ usehttps="off"
+ ) & stop
+}
+
+ruleset(name="ruleset_omhttp") {
+ action(
+ name="action_omhttp"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="on"
+ batch.maxsize="100"
+ batch.format="jsonarray"
+
+ retry="on"
+ retry.ruleset="ruleset_omhttp_retry"
+
+ # Auth
+ usehttps="off"
+ ) & stop
+}
+
+if $msg contains "msgnum:" then
+ call ruleset_omhttp
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint jsonarray
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-batch-jsonarray-vg.sh b/tests/omhttp-batch-jsonarray-vg.sh
new file mode 100755
index 0000000..a2300ee
--- /dev/null
+++ b/tests/omhttp-batch-jsonarray-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/omhttp-batch-jsonarray.sh
diff --git a/tests/omhttp-batch-jsonarray.sh b/tests/omhttp-batch-jsonarray.sh
new file mode 100755
index 0000000..41bbcdb
--- /dev/null
+++ b/tests/omhttp-batch-jsonarray.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+
+omhttp_start_server 0
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../contrib/omhttp/.libs/omhttp")
+
+main_queue(queue.dequeueBatchSize="2048")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="on"
+ batch.format="jsonarray"
+ batch.maxsize="1000"
+
+ # Auth
+ usehttps="off"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint jsonarray
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-batch-kafkarest-retry-vg.sh b/tests/omhttp-batch-kafkarest-retry-vg.sh
new file mode 100755
index 0000000..c0b8eb6
--- /dev/null
+++ b/tests/omhttp-batch-kafkarest-retry-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/omhttp-batch-kafkarest-retry.sh
diff --git a/tests/omhttp-batch-kafkarest-retry.sh b/tests/omhttp-batch-kafkarest-retry.sh
new file mode 100755
index 0000000..b81c6f0
--- /dev/null
+++ b/tests/omhttp-batch-kafkarest-retry.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=50000
+
+omhttp_start_server 0 --fail-every 100
+
+generate_conf
+add_conf '
+module(load="../contrib/omhttp/.libs/omhttp")
+
+main_queue(queue.dequeueBatchSize="2048")
+
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+# Echo message as-is for retry
+template(name="tpl_echo" type="string" string="%msg%")
+
+ruleset(name="ruleset_omhttp_retry") {
+ action(
+ name="action_omhttp"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl_echo"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="on"
+ batch.maxsize="100"
+ batch.format="kafkarest"
+
+ retry="on"
+ retry.ruleset="ruleset_omhttp_retry"
+
+ # Auth
+ usehttps="off"
+ ) & stop
+}
+
+ruleset(name="ruleset_omhttp") {
+ action(
+ name="action_omhttp"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="on"
+ batch.maxsize="100"
+ batch.format="kafkarest"
+
+ retry="on"
+ retry.ruleset="ruleset_omhttp_retry"
+
+ # Auth
+ usehttps="off"
+ ) & stop
+}
+
+if $msg contains "msgnum:" then
+ call ruleset_omhttp
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint kafkarest
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-batch-kafkarest.sh b/tests/omhttp-batch-kafkarest.sh
new file mode 100755
index 0000000..a9fcb1c
--- /dev/null
+++ b/tests/omhttp-batch-kafkarest.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=50000
+
+omhttp_start_server 0
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../contrib/omhttp/.libs/omhttp")
+
+main_queue(queue.dequeueBatchSize="2048")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="on"
+ batch.format="kafkarest"
+ batch.maxsize="100"
+
+ # Auth
+ usehttps="off"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint kafkarest
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-batch-lokirest-retry-vg.sh b/tests/omhttp-batch-lokirest-retry-vg.sh
new file mode 100755
index 0000000..c0b8eb6
--- /dev/null
+++ b/tests/omhttp-batch-lokirest-retry-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/omhttp-batch-kafkarest-retry.sh
diff --git a/tests/omhttp-batch-lokirest-retry.sh b/tests/omhttp-batch-lokirest-retry.sh
new file mode 100755
index 0000000..56eeaab
--- /dev/null
+++ b/tests/omhttp-batch-lokirest-retry.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=50000
+
+omhttp_start_server 0 --fail-every 100
+
+generate_conf
+add_conf '
+module(load="../contrib/omhttp/.libs/omhttp")
+
+main_queue(queue.dequeueBatchSize="2048")
+
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+# Echo message as-is for retry
+template(name="tpl_echo" type="string" string="%msg%")
+
+ruleset(name="ruleset_omhttp_retry") {
+ action(
+ name="action_omhttp"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl_echo"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="on"
+ batch.maxsize="100"
+ batch.format="lokirest"
+
+ retry="on"
+ retry.ruleset="ruleset_omhttp_retry"
+
+ # Auth
+ usehttps="off"
+ ) & stop
+}
+
+ruleset(name="ruleset_omhttp") {
+ action(
+ name="action_omhttp"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="on"
+ batch.maxsize="100"
+ batch.format="lokirest"
+
+ retry="on"
+ retry.ruleset="ruleset_omhttp_retry"
+
+ # Auth
+ usehttps="off"
+ ) & stop
+}
+
+if $msg contains "msgnum:" then
+ call ruleset_omhttp
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint lokirest
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-batch-lokirest-vg.sh b/tests/omhttp-batch-lokirest-vg.sh
new file mode 100755
index 0000000..e1eeca8
--- /dev/null
+++ b/tests/omhttp-batch-lokirest-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+# export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes --leak-check=full"
+
+source ${srcdir:=.}/omhttp-batch-lokirest.sh
diff --git a/tests/omhttp-batch-lokirest.sh b/tests/omhttp-batch-lokirest.sh
new file mode 100755
index 0000000..c36add7
--- /dev/null
+++ b/tests/omhttp-batch-lokirest.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=50000
+
+omhttp_start_server 0
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../contrib/omhttp/.libs/omhttp")
+
+main_queue(queue.dequeueBatchSize="2048")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="on"
+ batch.format="lokirest"
+ batch.maxsize="100"
+
+ # Auth
+ usehttps="off"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint lokirest
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-batch-newline.sh b/tests/omhttp-batch-newline.sh
new file mode 100755
index 0000000..19ef43b
--- /dev/null
+++ b/tests/omhttp-batch-newline.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=50000
+
+omhttp_start_server 0
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../contrib/omhttp/.libs/omhttp")
+
+main_queue(queue.dequeueBatchSize="2048")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="on"
+ batch.format="newline"
+ batch.maxsize="100"
+
+ # Auth
+ usehttps="off"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint newline
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-dynrestpath.sh b/tests/omhttp-dynrestpath.sh
new file mode 100755
index 0000000..60f22d9
--- /dev/null
+++ b/tests/omhttp-dynrestpath.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=10000
+export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+
+omhttp_start_server 0
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+template(name="dynrestpath" type="string" string="my/endpoint")
+
+module(load="../contrib/omhttp/.libs/omhttp")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ dynrestpath = "on"
+ restpath="dynrestpath"
+ batch="off"
+
+ # Auth
+ usehttps="off"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-httpheaderkey.sh b/tests/omhttp-httpheaderkey.sh
new file mode 100755
index 0000000..91f3253
--- /dev/null
+++ b/tests/omhttp-httpheaderkey.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=1000
+
+omhttp_start_server 0
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../contrib/omhttp/.libs/omhttp")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+ httpheaderkey="X-Insert-Key"
+ httpheadervalue="dummy-value"
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="off"
+
+ # Auth
+ usehttps="off"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-multiplehttpheaders.sh b/tests/omhttp-multiplehttpheaders.sh
new file mode 100755
index 0000000..b547bd0
--- /dev/null
+++ b/tests/omhttp-multiplehttpheaders.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=1000
+
+omhttp_start_server 0
+
+generate_conf
+add_conf '
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+module(load="../contrib/omhttp/.libs/omhttp")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+ httpheaders=[
+ "X-Insert-Key: dummy-value",
+ "X-Event-Source: logs"
+ ]
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ batch="off"
+
+ # Auth
+ usehttps="off"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp-retry-vg.sh b/tests/omhttp-retry-vg.sh
new file mode 100755
index 0000000..ecc74cf
--- /dev/null
+++ b/tests/omhttp-retry-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/omhttp-retry.sh
diff --git a/tests/omhttp-retry.sh b/tests/omhttp-retry.sh
new file mode 100755
index 0000000..f174f42
--- /dev/null
+++ b/tests/omhttp-retry.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Starting actual testbench
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=10000
+
+omhttp_start_server 0 --fail-every 1000
+
+generate_conf
+add_conf '
+module(load="../contrib/omhttp/.libs/omhttp")
+
+main_queue(queue.dequeueBatchSize="2048")
+
+template(name="tpl" type="string"
+ string="{\"msgnum\":\"%msg:F,58:2%\"}")
+
+if $msg contains "msgnum:" then
+ action(
+ # Payload
+ action.resumeRetryCount="-1"
+ name="my_http_action"
+ type="omhttp"
+ errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'"
+ template="tpl"
+
+ server="localhost"
+ serverport="'$omhttp_server_lstnport'"
+ restpath="my/endpoint"
+ checkpath="ping"
+ batch="off"
+
+ # Auth
+ usehttps="off"
+ )
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+omhttp_get_data $omhttp_server_lstnport my/endpoint
+omhttp_stop_server
+seq_check
+exit_test
diff --git a/tests/omhttp_server.py b/tests/omhttp_server.py
new file mode 100644
index 0000000..61e0e63
--- /dev/null
+++ b/tests/omhttp_server.py
@@ -0,0 +1,135 @@
+# call this via "python[3] script name"
+import argparse
+import json
+import os
+import zlib
+import base64
+
+try:
+ from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer # Python 2
+except ImportError:
+ from http.server import BaseHTTPRequestHandler, HTTPServer # Python 3
+
+# Keep track of data received at each path
+data = {}
+
+metadata = {'posts': 0, 'fail_after': 0, 'fail_every': -1, 'decompress': False, 'userpwd': ''}
+
+
+class MyHandler(BaseHTTPRequestHandler):
+ """
+ POST'd data is kept in the data global dict.
+ Keys are the path, values are the raw received data.
+ Two post requests to <host>:<port>/post/endpoint means data looks like...
+ {"/post/endpoint": ["{\"msgnum\":\"00001\"}", "{\"msgnum\":\"00001\"}"]}
+
+ GET requests return all data posted to that endpoint as a json list.
+ Note that rsyslog usually sends escaped json data, so some parsing may be needed.
+ A get request for <host>:<post>/post/endpoint responds with...
+ ["{\"msgnum\":\"00001\"}", "{\"msgnum\":\"00001\"}"]
+ """
+
+ def validate_auth(self):
+ # header format for basic authentication
+ # 'Authorization: Basic <base 64 encoded uid:pwd>'
+ if 'Authorization' not in self.headers:
+ self.send_response(401)
+ self.end_headers()
+ self.wfile.write(b'missing "Authorization" header')
+ return False
+
+ auth_header = self.headers['Authorization']
+ _, b64userpwd = auth_header.split()
+ userpwd = base64.b64decode(b64userpwd).decode('utf-8')
+ if userpwd != metadata['userpwd']:
+ self.send_response(401)
+ self.end_headers()
+ self.wfile.write(b'invalid auth: {0}'.format(userpwd))
+ return False
+
+ return True
+
+ def do_POST(self):
+ metadata['posts'] += 1
+
+ if metadata['userpwd']:
+ if not self.validate_auth():
+ return
+
+ if metadata['fail_with_400_after'] != -1 and metadata['posts'] > metadata['fail_with_400_after']:
+ self.send_response(400)
+ self.end_headers()
+ self.wfile.write(b'BAD REQUEST')
+ return
+
+ if metadata['posts'] > 1 and metadata['fail_every'] != -1 and metadata['posts'] % metadata['fail_every'] == 0:
+ self.send_response(500)
+ self.end_headers()
+ self.wfile.write(b'INTERNAL ERROR')
+ return
+
+ content_length = int(self.headers['Content-Length'] or 0)
+ raw_data = self.rfile.read(content_length)
+
+ if metadata['decompress']:
+ post_data = zlib.decompress(raw_data, 31)
+ else:
+ post_data = raw_data
+
+ if self.path not in data:
+ data[self.path] = []
+ data[self.path].append(post_data.decode('utf-8'))
+
+ res = json.dumps({'msg': 'ok'}).encode('utf8')
+
+ self.send_response(200)
+ self.send_header('Content-Type', 'application/json; charset=utf-8')
+ self.send_header('Content-Length', len(res))
+ self.end_headers()
+
+ self.wfile.write(res)
+ return
+
+ def do_GET(self):
+ if self.path in data:
+ result = data[self.path]
+ else:
+ result = []
+
+ res = json.dumps(result).encode('utf8')
+
+ self.send_response(200)
+ self.send_header('Content-Type', 'application/json; charset=utf-8')
+ self.send_header('Content-Length', len(res))
+ self.end_headers()
+
+ self.wfile.write(res)
+ return
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='Archive and delete core app log files')
+ parser.add_argument('-p', '--port', action='store', type=int, default=8080, help='port')
+ parser.add_argument('--port-file', action='store', type=str, default='', help='file to store listen port number')
+ parser.add_argument('-i', '--interface', action='store', type=str, default='localhost', help='port')
+ parser.add_argument('--fail-after', action='store', type=int, default=0, help='start failing after n posts')
+ parser.add_argument('--fail-every', action='store', type=int, default=-1, help='fail every n posts')
+ parser.add_argument('--fail-with-400-after', action='store', type=int, default=-1, help='fail with 400 after n posts')
+ parser.add_argument('--decompress', action='store_true', default=False, help='decompress posted data')
+ parser.add_argument('--userpwd', action='store', default='', help='only accept this user:password combination')
+ args = parser.parse_args()
+ metadata['fail_after'] = args.fail_after
+ metadata['fail_every'] = args.fail_every
+ metadata['fail_with_400_after'] = args.fail_with_400_after
+ metadata['decompress'] = args.decompress
+ metadata['userpwd'] = args.userpwd
+ server = HTTPServer((args.interface, args.port), MyHandler)
+ lstn_port = server.server_address[1]
+ pid = os.getpid()
+ print('starting omhttp test server at {interface}:{port} with pid {pid}'
+ .format(interface=args.interface, port=lstn_port, pid=pid))
+ if args.port_file != '':
+ f = open(args.port_file, "w")
+ f.write(str(lstn_port))
+ f.close()
+ server.serve_forever()
diff --git a/tests/omjournal-abort-no-template.sh b/tests/omjournal-abort-no-template.sh
new file mode 100755
index 0000000..d86c744
--- /dev/null
+++ b/tests/omjournal-abort-no-template.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# a very basic test for omjournal. Right now, we have no
+# reliable way of verifying that data was actually written
+# to the journal, but at least we check that rsyslog does
+# not abort when trying to use omjournal. Not high tech,
+# but better than nothing.
+# addd 2016-03-16 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omjournal/.libs/omjournal")
+
+action(type="omjournal")
+'
+startup
+./msleep 500
+shutdown_when_empty
+wait_shutdown
+# if we reach this, we have at least not aborted
+exit_test
diff --git a/tests/omjournal-abort-template.sh b/tests/omjournal-abort-template.sh
new file mode 100755
index 0000000..2461012
--- /dev/null
+++ b/tests/omjournal-abort-template.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# a very basic test for omjournal. Right now, we have no
+# reliable way of verifying that data was actually written
+# to the journal, but at least we check that rsyslog does
+# not abort when trying to use omjournal. Not high tech,
+# but better than nothing.
+# addd 2016-03-16 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omjournal/.libs/omjournal")
+
+template(name="outfmt" type="string" string="%msg%")
+action(type="omjournal" template="outfmt")
+'
+startup
+./msleep 500
+shutdown_when_empty
+wait_shutdown
+# if we reach this, we have at least not aborted
+exit_test
diff --git a/tests/omjournal-basic-no-template.sh b/tests/omjournal-basic-no-template.sh
new file mode 100755
index 0000000..a31caea
--- /dev/null
+++ b/tests/omjournal-basic-no-template.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# a basic test for omjournal.
+# addd 2016-03-18 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh require-journalctl
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omjournal/.libs/omjournal")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omjournal")
+'
+startup
+tcpflood -m1 -M "\"<133>2011-03-01T11:22:12Z host tag msgh RsysLoG-TESTBENCH $COOKIE\""
+./msleep 500
+shutdown_when_empty
+wait_shutdown
+# if we reach this, we have at least not aborted
+journalctl -r -t rsyslogd: |grep "RsysLoG-TESTBENCH $COOKIE"
+if [ $? -ne 1 ]; then
+ echo "error: cookie $COOKIE not found. Head of journal:"
+ journalctl -r -t rsyslogd: | head
+ exit 1
+fi
+exit_test
diff --git a/tests/omjournal-basic-template.sh b/tests/omjournal-basic-template.sh
new file mode 100755
index 0000000..bc48626
--- /dev/null
+++ b/tests/omjournal-basic-template.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# a very basic test for omjournal.
+# addd 2016-03-18 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh require-journalctl
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omjournal/.libs/omjournal")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg%")
+action(type="omjournal" template="outfmt")
+'
+
+# we generate a cookie so that we can find our record in journal
+COOKIE=`date`
+echo "COOKIE: $COOKIE"
+startup
+tcpflood -m1 -M "\"<133>2011-03-01T11:22:12Z host tag msgh RsysLoG-TESTBENCH $COOKIE\""
+./msleep 500
+shutdown_when_empty
+wait_shutdown
+# if we reach this, we have at least not aborted
+journalctl -r -t rsyslogd: |grep "RsysLoG-TESTBENCH $COOKIE"
+if [ $? -ne 1 ]; then
+ echo "error: cookie $COOKIE not found. Head of journal:"
+ journalctl -r -t rsyslogd: | head
+ exit 1
+fi
+exit_test
diff --git a/tests/omkafka-vg.sh b/tests/omkafka-vg.sh
new file mode 100755
index 0000000..81ca63c
--- /dev/null
+++ b/tests/omkafka-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/omkafka.sh
diff --git a/tests/omkafka.sh b/tests/omkafka.sh
new file mode 100755
index 0000000..5ce4bd6
--- /dev/null
+++ b/tests/omkafka.sh
@@ -0,0 +1,129 @@
+#!/bin/bash
+# added 2017-05-03 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+test_status unreliable 'https://github.com/rsyslog/rsyslog/issues/3197'
+check_command_available kafkacat
+
+export KEEP_KAFKA_RUNNING="YES"
+export TESTMESSAGES=100000
+export TESTMESSAGESFULL=$TESTMESSAGES
+
+export RANDTOPIC=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+
+# Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only.
+export EXTRA_EXITCHECK=dumpkafkalogs
+export EXTRA_EXIT=kafka
+echo Check and Stop previous instances of kafka/zookeeper
+download_kafka
+stop_zookeeper
+stop_kafka
+
+echo Create kafka/zookeeper instance and $RANDTOPIC topic
+start_zookeeper
+start_kafka
+create_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+# --- Create/Start omkafka sender config
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+# impstats in order to gain insight into error cases
+module(load="../plugins/impstats/.libs/impstats"
+ log.file="'$RSYSLOG_DYNNAME.pstats'"
+ interval="1" log.syslog="off")
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+$imdiagInjectDelayMode full
+
+module(load="../plugins/omkafka/.libs/omkafka")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+local4.* {
+ action( name="kafka-fwd"
+ type="omkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ template="outfmt"
+ confParam=[ "compression.codec=none",
+ "socket.timeout.ms=10000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "queue.buffering.max.messages=10000",
+ "enable.auto.commit=true",
+ "message.send.max.retries=1"]
+ topicConfParam=["message.timeout.ms=10000"]
+ partitions.auto="on"
+ closeTimeout="60000"
+ resubmitOnFailure="on"
+ keepFailedMessages="on"
+ failedMsgFile="'$RSYSLOG_OUT_LOG'-failed-'$RANDTOPIC'.data"
+ action.resumeInterval="1"
+ action.resumeRetryCount="2"
+ queue.saveonshutdown="on"
+ )
+ action( type="omfile" file="'$RSYSLOG_OUT_LOG'")
+ stop
+}
+
+action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'")
+'
+
+echo Starting sender instance [omkafka]
+startup
+
+echo Inject messages into rsyslog sender instance
+injectmsg 1 $TESTMESSAGES
+
+wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGESFULL 100
+
+# experimental: wait until kafkacat receives everything
+
+timeoutend=100
+timecounter=0
+
+while [ $timecounter -lt $timeoutend ]; do
+ (( timecounter++ ))
+
+ kafkacat -b localhost:29092 -e -C -o beginning -t $RANDTOPIC -f '%s' > $RSYSLOG_OUT_LOG
+ count=$(wc -l < ${RSYSLOG_OUT_LOG})
+ if [ $count -eq $TESTMESSAGESFULL ]; then
+ printf '**** wait-kafka-lines success, have %d lines ****\n\n' "$TESTMESSAGESFULL"
+ break
+ else
+ if [ "x$timecounter" == "x$timeoutend" ]; then
+ echo wait-kafka-lines failed, expected $TESTMESSAGESFULL got $count
+ shutdown_when_empty
+ wait_shutdown
+ error_exit 1
+ else
+ echo wait-file-lines not yet there, currently $count lines
+printf 'pstats data:\n'
+cat $RSYSLOG_DYNNAME.pstats
+ printf '\n'
+
+ $TESTTOOL_DIR/msleep 1000
+ fi
+ fi
+done
+unset count
+
+#end experimental
+
+echo Stopping sender instance [omkafka]
+shutdown_when_empty
+wait_shutdown
+
+#kafkacat -b localhost:29092 -e -C -o beginning -t $RANDTOPIC -f '%s' > $RSYSLOG_OUT_LOG
+#kafkacat -b localhost:29092 -e -C -o beginning -t $RANDTOPIC -f '%p@%o:%k:%s' > $RSYSLOG_OUT_LOG.extra
+
+# Delete topic to remove old traces before
+delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+# Dump Kafka log | uncomment if needed
+# dump_kafka_serverlog
+
+kafka_check_broken_broker $RSYSLOG_DYNNAME.othermsg
+seq_check 1 $TESTMESSAGESFULL -d
+
+exit_test
diff --git a/tests/omkafkadynakey.sh b/tests/omkafkadynakey.sh
new file mode 100755
index 0000000..a05a5ad
--- /dev/null
+++ b/tests/omkafkadynakey.sh
@@ -0,0 +1,154 @@
+#!/bin/bash
+# added 2018-12-18 by ludobrands
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+test_status unreliable 'https://github.com/rsyslog/rsyslog/issues/3197'
+check_command_available kafkacat
+
+export KEEP_KAFKA_RUNNING="YES"
+export TESTMESSAGES=100000
+export TESTMESSAGESFULL=$TESTMESSAGES
+
+export RANDTOPIC=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+
+# Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only.
+export EXTRA_EXITCHECK=dumpkafkalogs
+export EXTRA_EXIT=kafka
+echo Check and Stop previous instances of kafka/zookeeper
+download_kafka
+stop_zookeeper
+stop_kafka
+
+echo Create kafka/zookeeper instance and $RANDTOPIC topic
+start_zookeeper
+start_kafka
+create_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+# --- Create/Start omkafka sender config
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+# impstats in order to gain insight into error cases
+module(load="../plugins/impstats/.libs/impstats"
+ log.file="'$RSYSLOG_DYNNAME.pstats'"
+ interval="1" log.syslog="off")
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+$imdiagInjectDelayMode full
+
+module(load="../plugins/omkafka/.libs/omkafka")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+template(name="keyin" type="list"){
+ property(name="$.inkey")
+}
+
+local4.* {
+ set $.inkey = substring(field($msg,":",2),7,1);
+ action( name="kafka-fwd"
+ type="omkafka"
+ topic="'$RANDTOPIC'"
+ key="keyin"
+ dynaKey="on"
+ broker="localhost:29092"
+ template="outfmt"
+ confParam=[ "compression.codec=none",
+ "socket.timeout.ms=10000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "queue.buffering.max.messages=10000",
+ "enable.auto.commit=true",
+ "message.send.max.retries=1"]
+ topicConfParam=["message.timeout.ms=10000"]
+ partitions.auto="on"
+ closeTimeout="60000"
+ resubmitOnFailure="on"
+ keepFailedMessages="on"
+ failedMsgFile="'$RSYSLOG_OUT_LOG'-failed-'$RANDTOPIC'.data"
+ action.resumeInterval="1"
+ action.resumeRetryCount="2"
+ queue.saveonshutdown="on"
+ )
+ action( type="omfile" file="'$RSYSLOG_OUT_LOG'")
+ stop
+}
+
+action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'")
+'
+
+echo Starting sender instance [omkafka]
+startup
+
+echo Inject messages into rsyslog sender instance
+injectmsg 1 $TESTMESSAGES
+
+wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGESFULL 100
+
+# experimental: wait until kafkacat receives everything
+
+timeoutend=100
+timecounter=0
+
+while [ $timecounter -lt $timeoutend ]; do
+ (( timecounter++ ))
+
+ kafkacat -b localhost:29092 -e -C -o beginning -t $RANDTOPIC -f '%s' > $RSYSLOG_OUT_LOG
+ count=$(wc -l < ${RSYSLOG_OUT_LOG})
+ if [ $count -eq $TESTMESSAGESFULL ]; then
+ printf '**** wait-kafka-lines success, have %d lines ****\n\n' "$TESTMESSAGESFULL"
+ kafkacat -b localhost:29092 -e -C -o beginning -t $RANDTOPIC -f '%p %k\n' | sort | uniq > "$RSYSLOG_OUT_LOG.extra"
+ count=$(wc -l < "${RSYSLOG_OUT_LOG}.extra")
+ if [ $count -eq 10 ]; then
+ printf '**** partition check success, have 10 partition-key combinations ****\n\n'
+ break
+ else
+ shutdown_when_empty
+ wait_shutdown
+ printf '\n\nERROR: partition check failed, expected 10 got %s\n' "$count"
+ printf '\ņRAW DATA:\n'
+ kafkacat -b localhost:29092 -e -C -o beginning -t $RANDTOPIC -f '%p %k\n'
+ printf '\nCHECKED OUTPUT:\n'
+ cat "$RSYSLOG_OUT_LOG.extra"
+ error_exit 1
+ fi
+ else
+ if [ "x$timecounter" == "x$timeoutend" ]; then
+ echo wait-kafka-lines failed, expected $TESTMESSAGESFULL got $count
+ shutdown_when_empty
+ wait_shutdown
+ error_exit 1
+ else
+ echo wait-file-lines not yet there, currently $count lines
+ printf 'pstats data:\n'
+ # we use tail below to guard against overwhelming the
+ # logs if things go wild
+ tail -n 500 < $RSYSLOG_DYNNAME.pstats
+ printf '\n'
+
+ $TESTTOOL_DIR/msleep 1000
+ fi
+ fi
+echo end iteration $timecounter
+done
+unset count
+
+#end experimental
+
+echo Stopping sender instance [omkafka]
+shutdown_when_empty
+wait_shutdown
+
+#kafkacat -b localhost:29092 -e -C -o beginning -t $RANDTOPIC -f '%s' > $RSYSLOG_OUT_LOG
+#kafkacat -b localhost:29092 -e -C -o beginning -t $RANDTOPIC -f '%p@%o:%k:%s' > $RSYSLOG_OUT_LOG.extra
+
+# Delete topic to remove old traces before
+delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+# Dump Kafka log | uncomment if needed
+# dump_kafka_serverlog
+
+kafka_check_broken_broker $RSYSLOG_DYNNAME.othermsg
+seq_check 1 $TESTMESSAGESFULL -d
+
+exit_test
+
diff --git a/tests/ommail_errmsg_no_params.sh b/tests/ommail_errmsg_no_params.sh
new file mode 100755
index 0000000..096b617
--- /dev/null
+++ b/tests/ommail_errmsg_no_params.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# add 2018-09-25 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/ommail/.libs/ommail")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+action(type="ommail")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter 'mailto' required but not specified"
+
+exit_test
diff --git a/tests/omod-if-array-udp.sh b/tests/omod-if-array-udp.sh
new file mode 100755
index 0000000..7a87a8b
--- /dev/null
+++ b/tests/omod-if-array-udp.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%PRI%%timestamp%%hostname%%programname%%syslogtag%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: UDP request discarded from SERVER1/2741 to test_app:255.255.255.255/61601\""
+shutdown_when_empty
+wait_shutdown
+
+echo '167Mar 6 16:57:54172.20.245.8%PIX-7-710005%PIX-7-710005:' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/omod-if-array.sh b/tests/omod-if-array.sh
new file mode 100755
index 0000000..1915b04
--- /dev/null
+++ b/tests/omod-if-array.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%PRI%%timestamp%%hostname%%programname%%syslogtag%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: UDP request discarded from SERVER1/2741 to test_app:255.255.255.255/61601\""
+shutdown_when_empty
+wait_shutdown
+
+echo '167Mar 6 16:57:54172.20.245.8%PIX-7-710005%PIX-7-710005:' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/omprog-close-unresponsive-noterm.sh b/tests/omprog-close-unresponsive-noterm.sh
new file mode 100755
index 0000000..1ed43f5
--- /dev/null
+++ b/tests/omprog-close-unresponsive-noterm.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# This test checks that omprog does NOT send a TERM signal to the
+# external program when signalOnClose=off, closes the pipe, and kills
+# the unresponsive child if killUnresponsive=on.
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+main_queue(
+ queue.timeoutShutdown="60000" # give time to omprog to wait for the child
+)
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary="'$RSYSLOG_DYNNAME.'omprog-close-unresponsive-bin.sh"
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct" # the default; facilitates sync with the child process
+ confirmMessages="on" # facilitates sync with the child process
+ signalOnClose="off"
+ closeTimeout="1000" # ms
+ killUnresponsive="on" # default value: the value of signalOnClose
+ )
+}
+'
+cp -f $srcdir/testsuites/omprog-close-unresponsive-bin.sh $RSYSLOG_DYNNAME.omprog-close-unresponsive-bin.sh
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+. $srcdir/diag.sh ensure-no-process-exists $RSYSLOG_DYNNAME.omprog-close-unresponsive-bin.sh
+
+export EXPECTED="Starting
+Received msgnum:00000000:
+Received msgnum:00000001:
+Received msgnum:00000002:
+Received msgnum:00000003:
+Received msgnum:00000004:
+Received msgnum:00000005:
+Received msgnum:00000006:
+Received msgnum:00000007:
+Received msgnum:00000008:
+Received msgnum:00000009:
+Terminating unresponsively"
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/omprog-close-unresponsive-vg.sh b/tests/omprog-close-unresponsive-vg.sh
new file mode 100755
index 0000000..fea4da7
--- /dev/null
+++ b/tests/omprog-close-unresponsive-vg.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Same test than 'omprog-close-unresponsive.sh', but checking for memory
+# problems using valgrind. Note it is not necessary to repeat the
+# rest of checks (this simplifies the maintenance of the tests).
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+main_queue(
+ queue.timeoutShutdown="60000" # give time to omprog to wait for the child
+)
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary=`echo $srcdir/testsuites/omprog-close-unresponsive-bin.sh`
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct" # the default; facilitates sync with the child process
+ confirmMessages="on" # facilitates sync with the child process
+ signalOnClose="on"
+ closeTimeout="1000" # ms
+ #killUnresponsive="on" # default value: the value of signalOnClose
+ )
+}
+'
+startup_vg
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+exit_test
diff --git a/tests/omprog-close-unresponsive.sh b/tests/omprog-close-unresponsive.sh
new file mode 100755
index 0000000..3631f3f
--- /dev/null
+++ b/tests/omprog-close-unresponsive.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# This test checks that omprog sends a TERM signal to the external
+# program when signalOnClose=on, closes the pipe, and kills the
+# child if unresponsive.
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+main_queue(
+ queue.timeoutShutdown="60000" # give time to omprog to wait for the child
+)
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary="'$RSYSLOG_DYNNAME.'omprog-close-unresponsive-bin.sh"
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct" # the default; facilitates sync with the child process
+ confirmMessages="on" # facilitates sync with the child process
+ signalOnClose="on"
+ closeTimeout="1000" # ms
+ #killUnresponsive="on" # default value: the value of signalOnClose
+ )
+}
+'
+cp -f $srcdir/testsuites/omprog-close-unresponsive-bin.sh $RSYSLOG_DYNNAME.omprog-close-unresponsive-bin.sh
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+. $srcdir/diag.sh ensure-no-process-exists $RSYSLOG_DYNNAME.omprog-close-unresponsive-bin.sh
+
+export EXPECTED="Starting
+Received msgnum:00000000:
+Received msgnum:00000001:
+Received msgnum:00000002:
+Received msgnum:00000003:
+Received msgnum:00000004:
+Received msgnum:00000005:
+Received msgnum:00000006:
+Received msgnum:00000007:
+Received msgnum:00000008:
+Received msgnum:00000009:
+Received SIGTERM
+Terminating unresponsively"
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/omprog-defaults-vg.sh b/tests/omprog-defaults-vg.sh
new file mode 100755
index 0000000..53aae37
--- /dev/null
+++ b/tests/omprog-defaults-vg.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Same test than 'omprog-defaults.sh', but checking for memory
+# problems using valgrind. Note it is not necessary to repeat the
+# rest of checks (this simplifies the maintenance of the tests).
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary=`echo $srcdir/testsuites/omprog-defaults-bin.sh p1 p2 p3`
+ template="outfmt"
+ name="omprog_action"
+ )
+}
+'
+startup_vg
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+exit_test
diff --git a/tests/omprog-defaults.sh b/tests/omprog-defaults.sh
new file mode 100755
index 0000000..5c52550
--- /dev/null
+++ b/tests/omprog-defaults.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# This test tests omprog using the default values for all non-mandatory
+# settings. It also checks that command-line parameters are correctly
+# passed to the external program.
+
+# NOTE: Because the omprog feedback mode is not used in this test
+# (confirmMessages=off), it is difficult to synchronize the execution
+# of the external program with the test code. For this reason, it would
+# be difficult to test for negative cases (e.g. restart of the program
+# if it terminates prematurely) without making the test racy. So, we
+# only test a happy case: the program processes all logs received and
+# exits when the pipe is closed. After closing the pipe, omprog will
+# wait for the program to terminate during a timeout of 5 seconds
+# (default value of closeTimeout), which should be sufficient for the
+# program to write its output.
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary=`echo $srcdir/testsuites/omprog-defaults-bin.sh p1 p2 p3`
+ template="outfmt"
+ name="omprog_action"
+ )
+}
+'
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="Starting with parameters: p1 p2 p3
+Received msgnum:00000000:
+Received msgnum:00000001:
+Received msgnum:00000002:
+Received msgnum:00000003:
+Received msgnum:00000004:
+Received msgnum:00000005:
+Received msgnum:00000006:
+Received msgnum:00000007:
+Received msgnum:00000008:
+Received msgnum:00000009:
+Terminating normally"
+
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/omprog-feedback-mt.sh b/tests/omprog-feedback-mt.sh
new file mode 100755
index 0000000..1fdc6d9
--- /dev/null
+++ b/tests/omprog-feedback-mt.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Similar to the 'omprog-feedback.sh' test, with multiple worker threads
+# on high load, and a given error rate (percentage of failed messages, i.e.
+# confirmed as failed by the program). Note: the action retry interval
+# (1 second) causes a very low throughput; we need to set a very low error
+# rate to avoid the test lasting too much.
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "On Solaris, this test causes rsyslog to hang for unknown reasons"
+if [ "$CC" == "gcc" ] && [[ "$CFLAGS" == *"-coverage"* ]]; then
+ printf 'This test does not work with gcc coverage instrumentation\n'
+ printf 'It will hang, but we do not know why. See\n'
+ printf 'https://github.com/rsyslog/rsyslog/issues/3361\n'
+ exit 77
+fi
+
+NUMMESSAGES=10000 # number of logs to send
+ERROR_RATE_PERCENT=1 # percentage of logs to be retried
+
+export command_line="$srcdir/testsuites/omprog-feedback-mt-bin.sh $ERROR_RATE_PERCENT"
+
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+main_queue(
+ queue.timeoutShutdown="30000" # long shutdown timeout for the main queue
+)
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary=`echo $command_line`
+ template="outfmt"
+ name="omprog_action"
+ confirmMessages="on"
+ queue.type="LinkedList" # use a dedicated queue
+ queue.workerThreads="10" # ...with multiple workers
+ queue.size="10000" # ...high capacity (default is 1000)
+ queue.timeoutShutdown="60000" # ...and a long shutdown timeout
+ action.resumeInterval="1" # retry interval: 1 second
+ )
+}
+'
+startup
+injectmsg 0 $NUMMESSAGES
+wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/omprog-feedback-timeout.sh b/tests/omprog-feedback-timeout.sh
new file mode 100755
index 0000000..7b6361a
--- /dev/null
+++ b/tests/omprog-feedback-timeout.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# This test tests the feedback feature of omprog (confirmMessages=on),
+# by checking that omprog restarts the program if it does not send the
+# feedback before the configured 'confirmTimeout'. Also tests the
+# keep-alive feature.
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary=`echo $srcdir/testsuites/omprog-feedback-timeout-bin.sh`
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct" # the default; facilitates sync with the child process
+ confirmMessages="on"
+ confirmTimeout="2000" # 2 seconds
+ reportFailures="on"
+ )
+}
+'
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="Starting
+<= OK
+=> msgnum:00000000:
+<= OK
+=> msgnum:00000001:
+<= OK
+=> msgnum:00000002:
+<= OK
+=> msgnum:00000003:
+<= OK
+=> msgnum:00000004:
+<= (timeout)
+Starting
+<= OK
+=> msgnum:00000004:
+<= OK
+=> msgnum:00000005:
+<= OK
+=> msgnum:00000006:
+<= OK
+=> msgnum:00000007:
+<= ........OK
+=> msgnum:00000008:
+<= OK
+=> msgnum:00000009:
+<= OK"
+
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/omprog-feedback-vg.sh b/tests/omprog-feedback-vg.sh
new file mode 100755
index 0000000..62545be
--- /dev/null
+++ b/tests/omprog-feedback-vg.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Same test than 'omprog-feedback.sh', but checking for memory
+# problems using valgrind. Note it is not necessary to repeat the
+# rest of checks (this simplifies the maintenance of the tests).
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary=`echo $srcdir/testsuites/omprog-feedback-bin.sh`
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct"
+ confirmMessages="on"
+ action.resumeInterval="1"
+ )
+}
+'
+startup_vg
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+exit_test
diff --git a/tests/omprog-feedback.sh b/tests/omprog-feedback.sh
new file mode 100755
index 0000000..464ce33
--- /dev/null
+++ b/tests/omprog-feedback.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# This test tests the feedback feature of omprog (confirmMessages=on),
+# by checking that omprog re-sends to the external program the messages
+# it has failed to process.
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary="'$srcdir'/testsuites/omprog-feedback-bin.sh"
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct" # the default; facilitates sync with the child process
+ confirmMessages="on"
+ reportFailures="on"
+ action.resumeInterval="1" # retry interval: 1 second
+# action.resumeRetryCount="0" # the default; no need to increase since
+ # the action resumes immediately
+ )
+}
+'
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="<= OK
+=> msgnum:00000000:
+<= OK
+=> msgnum:00000001:
+<= OK
+=> msgnum:00000002:
+<= OK
+=> msgnum:00000003:
+<= OK
+=> msgnum:00000004:
+<= Error: could not process log message
+=> msgnum:00000004:
+<= Error: could not process log message
+=> msgnum:00000004:
+<= OK
+=> msgnum:00000005:
+<= OK
+=> msgnum:00000006:
+<= OK
+=> msgnum:00000007:
+<= Error: could not process log message
+=> msgnum:00000007:
+<= Error: could not process log message
+=> msgnum:00000007:
+<= OK
+=> msgnum:00000008:
+<= OK
+=> msgnum:00000009:
+<= OK"
+
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/omprog-if-error.sh b/tests/omprog-if-error.sh
new file mode 100755
index 0000000..89e035e
--- /dev/null
+++ b/tests/omprog-if-error.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# This test tests omprog if omprog detects errors in the calling
+# interface, namely a missing LF on input messages
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%")
+
+if (prifilt("local4.*") and $msg contains "msgnum:") then {
+ action(type="omprog" binary="'$srcdir'/testsuites/omprog-defaults-bin.sh p1 p2 p3"
+ template="outfmt" name="omprog_action")
+} else {
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.othermsg")
+}
+'
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+cat $RSYSLOG_DYNNAME.othermsg
+
+content_check 'must be terminated with \n' $RSYSLOG_DYNNAME.othermsg
+
+export EXPECTED="Starting with parameters: p1 p2 p3
+Received msgnum:00000000:
+Received msgnum:00000001:
+Received msgnum:00000002:
+Received msgnum:00000003:
+Received msgnum:00000004:
+Received msgnum:00000005:
+Received msgnum:00000006:
+Received msgnum:00000007:
+Received msgnum:00000008:
+Received msgnum:00000009:
+Terminating normally"
+
+cmp_exact $RSYSLOG_OUT_LOG
+exit_test
diff --git a/tests/omprog-output-capture-mt.sh b/tests/omprog-output-capture-mt.sh
new file mode 100755
index 0000000..ba1f86e
--- /dev/null
+++ b/tests/omprog-output-capture-mt.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Similar to the 'omprog-output-capture.sh' test, with multiple worker
+# threads on high load. Checks that the lines concurrently emitted to
+# stdout/stderr by the various program instances are not intermingled in
+# the output file (i.e., are captured atomically by omprog) when 1) the
+# lines are less than PIPE_BUF bytes long and 2) the program writes the
+# lines in unbuffered or line-buffered mode.
+
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on all flavors of Solaris (problems with Python?)"
+if [ "$CC" == "gcc" ] && [[ "$CFLAGS" == *"-coverage"* ]]; then
+ printf 'This test does not work with gcc coverage instrumentation\n'
+ printf 'It will hang, but we do not know why. See\n'
+ printf 'https://github.com/rsyslog/rsyslog/issues/3361\n'
+ exit 77
+fi
+
+export NUMMESSAGES=20000
+
+if [[ "$(uname)" == "Linux" ]]; then
+ export LINE_LENGTH=4095 # 4KB minus 1 byte (for the newline char)
+else
+ export LINE_LENGTH=511 # 512 minus 1 byte (for the newline char)
+fi
+
+empty_check() {
+ if [ $(wc -l < "$RSYSLOG_OUT_LOG") -ge $((NUMMESSAGES * 2)) ]; then
+ return 0
+ fi
+ return 1
+}
+export QUEUE_EMPTY_CHECK_FUNC=empty_check
+
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+main_queue(
+ queue.timeoutShutdown="60000" # long shutdown timeout for the main queue
+)
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary="'$PYTHON' '$srcdir'/testsuites/omprog-output-capture-mt-bin.py '$LINE_LENGTH'"
+ template="outfmt"
+ name="omprog_action"
+ queue.type="LinkedList" # use a dedicated queue
+ queue.workerThreads="10" # ...with many workers
+ queue.timeoutShutdown="60000" # ...and a long shutdown timeout
+ closeTimeout="10000" # wait enough for program to terminate
+ output=`echo $RSYSLOG_OUT_LOG`
+ fileCreateMode="0644"
+ )
+}
+'
+startup
+
+# Issue a HUP signal when the output-capture thread has not started yet,
+# to check that this case is handled correctly (the output file has not
+# been opened yet, so omprog must not try to reopen it).
+issue_HUP
+
+injectmsg 0 $NUMMESSAGES
+
+# Issue more HUP signals to cause the output file to be reopened during
+# writing (not a complete test of this feature, but at least we check it
+# doesn't break the output).
+issue_HUP
+./msleep 1000
+issue_HUP
+./msleep 1000
+issue_HUP
+
+#wait_file_lines "$RSYSLOG_OUT_LOG" $((NUMMESSAGES * 2))
+shutdown_when_empty
+wait_shutdown
+
+line_num=0
+while IFS= read -r line; do
+ ((line_num++))
+ if [[ ${#line} != $LINE_LENGTH ]]; then
+ echo "intermingled line in captured output: line: $line_num, length: ${#line} (expected: $LINE_LENGTH)"
+ echo "$line"
+ error_exit 1
+ fi
+done < $RSYSLOG_OUT_LOG
+
+if (( line_num != NUMMESSAGES * 2 )); then
+ echo "unexpected number of lines in captured output: $line_num (expected: $((NUMMESSAGES * 2)))"
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/omprog-output-capture-vg.sh b/tests/omprog-output-capture-vg.sh
new file mode 100755
index 0000000..28975a6
--- /dev/null
+++ b/tests/omprog-output-capture-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+export RS_TEST_VALGRIND_EXTRA_OPTS="--child-silent-after-fork=yes"
+source ${srcdir:-.}/omprog-output-capture.sh
diff --git a/tests/omprog-output-capture.sh b/tests/omprog-output-capture.sh
new file mode 100755
index 0000000..bbe62e9
--- /dev/null
+++ b/tests/omprog-output-capture.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# This test tests the 'output' setting of omprog when the feedback
+# feature is not used (confirmMessages=off).
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary="'$srcdir'/testsuites/omprog-output-capture-bin.sh"
+ template="outfmt"
+ name="omprog_action"
+ output="'$RSYSLOG_OUT_LOG'"
+ fileCreateMode="0644" # default is 0600
+ )
+}
+'
+startup
+injectmsg 0 10
+wait_file_lines "$RSYSLOG_OUT_LOG" 22
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="[stdout] Starting
+[stderr] Starting
+[stdout] Received msgnum:00000000:
+[stderr] Received msgnum:00000000:
+[stdout] Received msgnum:00000001:
+[stderr] Received msgnum:00000001:
+[stdout] Received msgnum:00000002:
+[stderr] Received msgnum:00000002:
+[stdout] Received msgnum:00000003:
+[stderr] Received msgnum:00000003:
+[stdout] Received msgnum:00000004:
+[stderr] Received msgnum:00000004:
+[stdout] Received msgnum:00000005:
+[stderr] Received msgnum:00000005:
+[stdout] Received msgnum:00000006:
+[stderr] Received msgnum:00000006:
+[stdout] Received msgnum:00000007:
+[stderr] Received msgnum:00000007:
+[stdout] Received msgnum:00000008:
+[stderr] Received msgnum:00000008:
+[stdout] Received msgnum:00000009:
+[stderr] Received msgnum:00000009:
+[stdout] Terminating normally
+[stderr] Terminating normally"
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/omprog-restart-terminated-outfile.sh b/tests/omprog-restart-terminated-outfile.sh
new file mode 100755
index 0000000..e8afe33
--- /dev/null
+++ b/tests/omprog-restart-terminated-outfile.sh
@@ -0,0 +1,135 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Similar to the 'omprog-restart-terminated.sh' test, using the 'output'
+# parameter. Checks that no file descriptors are leaked across restarts
+# of the program when stderr is being captured to a file.
+
+. ${srcdir:=.}/diag.sh init
+check_command_available lsof
+
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary="'$RSYSLOG_DYNNAME'.omprog-restart-terminated-bin.sh"
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct" # the default; facilitates sync with the child process
+ confirmMessages="on" # facilitates sync with the child process
+ action.resumeRetryCount="3"
+ action.resumeInterval="1"
+ action.reportSuspensionContinuation="on"
+ signalOnClose="off"
+ output=`echo $RSYSLOG2_OUT_LOG`
+ )
+}
+'
+
+# We need a test-specific program name, as the test needs to signal the child process
+cp -f $srcdir/testsuites/omprog-restart-terminated-bin.sh $RSYSLOG_DYNNAME.omprog-restart-terminated-bin.sh
+
+# On Solaris 10, the output of ps is truncated for long process names; use /usr/ucb/ps instead:
+if [[ $(uname) = "SunOS" && $(uname -r) = "5.10" ]]; then
+ function get_child_pid {
+ /usr/ucb/ps -awwx | grep "$RSYSLOG_DYNNAME.[o]mprog-restart-terminated-bin.sh" | awk '{ print $1 }'
+ }
+else
+ function get_child_pid {
+ ps -ef | grep "$RSYSLOG_DYNNAME.[o]mprog-restart-terminated-bin.sh" | awk '{ print $2 }'
+ }
+fi
+
+startup
+injectmsg 0 1
+wait_queueempty
+
+pid=$(getpid)
+start_fd_count=$(lsof -p $pid | wc -l)
+
+injectmsg 1 1
+injectmsg 2 1
+wait_queueempty
+
+kill -s USR1 $(get_child_pid)
+./msleep 100
+
+injectmsg 3 1
+injectmsg 4 1
+wait_queueempty
+
+kill -s TERM $(get_child_pid)
+./msleep 100
+
+injectmsg 5 1
+injectmsg 6 1
+injectmsg 7 1
+wait_queueempty
+
+kill -s KILL $(get_child_pid)
+./msleep 100
+
+injectmsg 8 1
+injectmsg 9 1
+wait_queueempty
+
+end_fd_count=$(lsof -p $pid | wc -l)
+
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="Starting
+Received msgnum:00000000:
+Received msgnum:00000001:
+Received msgnum:00000002:
+Received SIGUSR1, will terminate after the next message
+Received msgnum:00000003:
+Terminating without confirming the last message
+Starting
+Received msgnum:00000003:
+Received msgnum:00000004:
+Received SIGTERM, terminating
+Starting
+Received msgnum:00000005:
+Received msgnum:00000006:
+Received msgnum:00000007:
+Starting
+Received msgnum:00000008:
+Received msgnum:00000009:
+Terminating normally"
+
+cmp_exact $RSYSLOG_OUT_LOG
+
+export EXPECTED="[stderr] Starting
+[stderr] Received msgnum:00000000:
+[stderr] Received msgnum:00000001:
+[stderr] Received msgnum:00000002:
+[stderr] Received SIGUSR1, will terminate after the next message
+[stderr] Received msgnum:00000003:
+[stderr] Terminating without confirming the last message
+[stderr] Starting
+[stderr] Received msgnum:00000003:
+[stderr] Received msgnum:00000004:
+[stderr] Received SIGTERM, terminating
+[stderr] Starting
+[stderr] Received msgnum:00000005:
+[stderr] Received msgnum:00000006:
+[stderr] Received msgnum:00000007:
+[stderr] Starting
+[stderr] Received msgnum:00000008:
+[stderr] Received msgnum:00000009:
+[stderr] Terminating normally"
+
+cmp_exact $RSYSLOG2_OUT_LOG
+
+if [[ "$start_fd_count" != "$end_fd_count" ]]; then
+ echo "file descriptor leak: started with $start_fd_count open files, ended with $end_fd_count"
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/omprog-restart-terminated-vg.sh b/tests/omprog-restart-terminated-vg.sh
new file mode 100755
index 0000000..a090c30
--- /dev/null
+++ b/tests/omprog-restart-terminated-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# addd 2019-04-15 by RGerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/omprog-restart-terminated.sh
diff --git a/tests/omprog-restart-terminated.sh b/tests/omprog-restart-terminated.sh
new file mode 100755
index 0000000..8fbc99e
--- /dev/null
+++ b/tests/omprog-restart-terminated.sh
@@ -0,0 +1,155 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# This test checks that omprog restarts the external program when it
+# terminates prematurely, and that it does so without leaking file
+# descriptors. Two cases are checked: termination of the program when
+# omprog is going to write to the pipe (to send a message to the
+# program), and when omprog is going to read from the pipe (when it
+# is expecting the program to confirm the last message).
+
+. ${srcdir:=.}/diag.sh init
+check_command_available lsof
+
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary="'$RSYSLOG_DYNNAME'.omprog-restart-terminated-bin.sh"
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct" # the default; facilitates sync with the child process
+ confirmMessages="on" # facilitates sync with the child process
+ action.resumeRetryCount="3"
+ action.resumeInterval="1"
+ action.reportSuspensionContinuation="on"
+ signalOnClose="off"
+ )
+}
+
+syslog.* {
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG2_OUT_LOG`)
+}
+'
+
+# We need a test-specific program name, as the test needs to signal the child process
+cp -f $srcdir/testsuites/omprog-restart-terminated-bin.sh $RSYSLOG_DYNNAME.omprog-restart-terminated-bin.sh
+
+# On Solaris 10, the output of ps is truncated for long process names; use /usr/ucb/ps instead:
+if [[ $(uname) = "SunOS" && $(uname -r) = "5.10" ]]; then
+ function get_child_pid {
+ /usr/ucb/ps -awwx | grep "$RSYSLOG_DYNNAME.[o]mprog-restart-terminated-bin.sh" | awk '{ print $1 }'
+ }
+else
+ function get_child_pid {
+ ps -ef | grep "$RSYSLOG_DYNNAME.[o]mprog-restart-terminated-bin.sh" | awk '{ print $2 }'
+ }
+fi
+
+startup
+injectmsg 0 1
+wait_queueempty
+
+pid=$(getpid)
+echo PID: $pid
+start_fd_count=$(lsof -p $pid | wc -l)
+
+injectmsg 1 1
+injectmsg 2 1
+wait_queueempty
+
+child_pid_1=$(get_child_pid)
+kill -s USR1 $child_pid_1
+./msleep 100
+
+injectmsg 3 1
+injectmsg 4 1
+wait_queueempty
+
+child_pid_2=$(get_child_pid)
+kill -s TERM $child_pid_2
+./msleep 100
+
+injectmsg 5 1
+injectmsg 6 1
+injectmsg 7 1
+wait_queueempty
+
+child_pid_3=$(get_child_pid)
+kill -s KILL $child_pid_3
+./msleep 100
+
+injectmsg 8 1
+injectmsg 9 1
+wait_queueempty
+
+end_fd_count=$(lsof -p $pid | wc -l)
+child_pid_4=$(get_child_pid)
+child_lsof=$(lsof -a -d 0-65535 -p $child_pid_4 | awk '$4 != "255r" { print $4 " " $9 }')
+
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="Starting
+Received msgnum:00000000:
+Received msgnum:00000001:
+Received msgnum:00000002:
+Received SIGUSR1, will terminate after the next message
+Received msgnum:00000003:
+Terminating without confirming the last message
+Starting
+Received msgnum:00000003:
+Received msgnum:00000004:
+Received SIGTERM, terminating
+Starting
+Received msgnum:00000005:
+Received msgnum:00000006:
+Received msgnum:00000007:
+Starting
+Received msgnum:00000008:
+Received msgnum:00000009:
+Terminating normally"
+cmp_exact $RSYSLOG_OUT_LOG
+
+if [[ "$start_fd_count" != "$end_fd_count" ]]; then
+ echo "file descriptor leak: started with $start_fd_count open files, ended with $end_fd_count"
+ error_exit 1
+fi
+
+# Check that the child process does not inherit open fds from rsyslog
+# (apart from the pipes), and that stderr is redirected to /dev/null.
+# Ignore fd 255, which bash opens for internal use.
+
+EXPECTED_CHILD_LSOF="FD NAME
+0r pipe
+1w pipe
+2w /dev/null"
+
+# On Solaris, lsof gives this alternate output:
+EXPECTED_CHILD_LSOF_2="FD NAME
+0u (fifofs)
+1u (fifofs)
+2w "
+
+if [[ "$child_lsof" != "$EXPECTED_CHILD_LSOF" && "$child_lsof" != "$EXPECTED_CHILD_LSOF_2" ]]; then
+ echo "unexpected open files for child process:"
+ echo "$child_lsof"
+ error_exit 1
+fi
+
+# Check also that child process terminations are reported correctly.
+# When the reportChildProcessExits global parameter is "errors" (the default),
+# only non-zero exit codes are reported.
+content_check "(pid $child_pid_1) terminated; will be restarted" $RSYSLOG2_OUT_LOG
+custom_assert_content_missing "(pid $child_pid_1) exited with status" $RSYSLOG2_OUT_LOG
+content_check "(pid $child_pid_2) terminated; will be restarted" $RSYSLOG2_OUT_LOG
+content_check "(pid $child_pid_2) exited with status 1" $RSYSLOG2_OUT_LOG
+content_check "(pid $child_pid_3) terminated; will be restarted" $RSYSLOG2_OUT_LOG
+content_check "(pid $child_pid_3) terminated by signal 9" $RSYSLOG2_OUT_LOG
+
+exit_test
diff --git a/tests/omprog-single-instance-outfile.sh b/tests/omprog-single-instance-outfile.sh
new file mode 100755
index 0000000..2ab789e
--- /dev/null
+++ b/tests/omprog-single-instance-outfile.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Similar to the 'omprog-single-instance.sh' test, using the 'output'
+# parameter. Checks that the output of the program is correctly captured
+# when the 'forceSingleInstance' flag is enabled.
+
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on Solaris"
+export NUMMESSAGES=10000 # number of logs to send
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary="'$srcdir'/testsuites/omprog-single-instance-bin.sh"
+ template="outfmt"
+ name="omprog_action"
+ confirmMessages="on"
+ forceSingleInstance="on"
+ queue.type="LinkedList" # use a dedicated queue
+ queue.workerThreads="10" # ...with multiple workers
+ queue.size="5000" # ...high capacity (default is 1000)
+ queue.timeoutShutdown="30000" # ...and a long shutdown timeout
+ output="'$RSYSLOG2_OUT_LOG'"
+ )
+}
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+
+EXPECTED_LINE_LENGTH=34 # example line: '[stderr] Received msgnum:00009880:'
+line_num=0
+while IFS= read -r line; do
+ ((line_num++))
+ if (( line_num == 1 )); then
+ if [[ "$line" != "[stderr] Starting" ]]; then
+ echo "unexpected first line in captured stderr: $line"
+ error_exit 1
+ fi
+ elif (( line_num == NUMMESSAGES + 2 )); then
+ if [[ "$line" != "[stderr] Terminating" ]]; then
+ echo "unexpected last line in captured stderr: $line"
+ error_exit 1
+ fi
+ elif [[ ${#line} != $EXPECTED_LINE_LENGTH ]]; then
+ echo "unexpected line in captured stderr (line $line_num): $line"
+ error_exit 1
+ fi
+done < $RSYSLOG2_OUT_LOG
+
+if (( line_num != NUMMESSAGES + 2 )); then
+ echo "unexpected line count in captured stderr: $line_num (expected: $((NUMMESSAGES + 2)))"
+ error_exit 1
+fi
+
+# Note: we use awk here to remove leading spaces returned by wc on FreeBSD
+line_count=$(wc -l < ${RSYSLOG_OUT_LOG} | awk '{print $1}')
+if (( line_count != NUMMESSAGES + 2 )); then
+ echo "unexpected line count in output: $line_count (expected: $((NUMMESSAGES + 2)))"
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/omprog-single-instance-vg.sh b/tests/omprog-single-instance-vg.sh
new file mode 100755
index 0000000..5b7eb0c
--- /dev/null
+++ b/tests/omprog-single-instance-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# addd 2019-04-15 by RGerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/omprog-single-instance.sh
diff --git a/tests/omprog-single-instance.sh b/tests/omprog-single-instance.sh
new file mode 100755
index 0000000..64b088c
--- /dev/null
+++ b/tests/omprog-single-instance.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# This test tests the omprog 'forceSingleInstance' flag by checking
+# that only one instance of the program is started when multiple
+# workers are in effect.
+
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on Solaris "
+export NUMMESSAGES=10000 # number of logs to send
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary="'$srcdir'/testsuites/omprog-single-instance-bin.sh"
+ template="outfmt"
+ name="omprog_action"
+ confirmMessages="on"
+ forceSingleInstance="on"
+ queue.type="LinkedList" # use a dedicated queue
+ queue.workerThreads="10" # ...with multiple workers
+ queue.size="5000" # ...high capacity (default is 1000)
+ queue.timeoutShutdown="30000" # ...and a long shutdown timeout
+ )
+}
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+
+EXPECTED_LINE_LENGTH=25 # example line: 'Received msgnum:00009880:'
+line_num=0
+while IFS= read -r line; do
+ ((line_num++))
+ if (( line_num == 1 )); then
+ if [[ "$line" != "Starting" ]]; then
+ echo "unexpected first line in output: $line"
+ error_exit 1
+ fi
+ elif (( line_num == NUMMESSAGES + 2 )); then
+ if [[ "$line" != "Terminating" ]]; then
+ echo "unexpected last line in output: $line"
+ error_exit 1
+ fi
+ elif [[ ${#line} != $EXPECTED_LINE_LENGTH ]]; then
+ echo "unexpected line in output (line $line_num): $line"
+ error_exit 1
+ fi
+done < $RSYSLOG_OUT_LOG
+
+if (( line_num != NUMMESSAGES + 2 )); then
+ echo "unexpected line count in output: $line_num (expected: $((NUMMESSAGES + 2)))"
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/omprog-transactions-failed-commits.sh b/tests/omprog-transactions-failed-commits.sh
new file mode 100755
index 0000000..3e36a32
--- /dev/null
+++ b/tests/omprog-transactions-failed-commits.sh
@@ -0,0 +1,158 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# This test tests omprog with the confirmMessages=on and useTransactions=on
+# parameters, with the external program returning an error on certain
+# transaction commits.
+
+. ${srcdir:=.}/diag.sh init
+
+uname
+if [ $(uname) = "SunOS" ] ; then
+ # On Solaris, this test causes rsyslog to hang. This is presumably due
+ # to issue #2356 in the rsyslog core, which doesn't seem completely
+ # corrected. TODO: re-enable this test when the issue is corrected.
+ echo "Solaris: FIX ME"
+ exit 77
+fi
+
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary=`echo $srcdir/testsuites/omprog-transactions-bin.sh --failed_commits`
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct" # the default; facilitates sync with the child process
+ queue.dequeueBatchSize="6"
+ confirmMessages="on"
+ useTransactions="on"
+ action.resumeRetryCount="10"
+ action.resumeInterval="1"
+ )
+}
+'
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+
+# Since the transaction boundaries are not deterministic, we cannot check for
+# an exact expected output. We must check the output programmatically.
+
+transaction_state="NONE"
+status_expected=true
+messages_to_commit=()
+messages_processed=()
+line_num=1
+error=
+
+while IFS= read -r line; do
+ if [[ $status_expected == true ]]; then
+ case "$transaction_state" in
+ "NONE")
+ if [[ "$line" != "<= OK" ]]; then
+ error="expecting an OK status from script"
+ break
+ fi
+ ;;
+ "STARTED")
+ if [[ "$line" != "<= OK" ]]; then
+ error="expecting an OK status from script"
+ break
+ fi
+ transaction_state="ACTIVE"
+ ;;
+ "ACTIVE")
+ if [[ "$line" != "<= DEFER_COMMIT" ]]; then
+ error="expecting a DEFER_COMMIT status from script"
+ break
+ fi
+ ;;
+ "COMMITTED")
+ if [[ "$line" == "<= Error: could not commit transaction" ]]; then
+ messages_to_commit=()
+ transaction_state="NONE"
+ else
+ if [[ "$line" != "<= OK" ]]; then
+ error="expecting an OK status from script"
+ break
+ fi
+ messages_processed+=("${messages_to_commit[@]}")
+ messages_to_commit=()
+ transaction_state="NONE"
+ fi
+ ;;
+ esac
+ status_expected=false;
+ else
+ if [[ "$line" == "=> BEGIN TRANSACTION" ]]; then
+ if [[ "$transaction_state" != "NONE" ]]; then
+ error="unexpected transaction start"
+ break
+ fi
+ transaction_state="STARTED"
+ elif [[ "$line" == "=> COMMIT TRANSACTION" ]]; then
+ if [[ "$transaction_state" != "ACTIVE" ]]; then
+ error="unexpected transaction commit"
+ break
+ fi
+ transaction_state="COMMITTED"
+ else
+ if [[ "$transaction_state" != "ACTIVE" ]]; then
+ error="unexpected message outside a transaction"
+ break
+ fi
+ if [[ "$line" != "=> msgnum:"* ]]; then
+ error="unexpected message contents"
+ break
+ fi
+ prefix_to_remove="=> "
+ messages_to_commit+=("${line#$prefix_to_remove}")
+ fi
+ status_expected=true;
+ fi
+ ((line_num++))
+done < $RSYSLOG_OUT_LOG
+
+if [[ -z "$error" && "$transaction_state" != "NONE" ]]; then
+ error="unexpected end of file (transaction state: $transaction_state)"
+fi
+
+if [[ -n "$error" ]]; then
+ echo "$RSYSLOG_OUT_LOG: line $line_num: $error"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+# Since the order in which failed messages are retried by rsyslog is not
+# deterministic, we sort the processed messages before checking them.
+IFS=$'\n' messages_sorted=($(sort <<<"${messages_processed[*]}"))
+unset IFS
+
+expected_messages=(
+ "msgnum:00000000:"
+ "msgnum:00000001:"
+ "msgnum:00000002:"
+ "msgnum:00000003:"
+ "msgnum:00000004:"
+ "msgnum:00000005:"
+ "msgnum:00000006:"
+ "msgnum:00000007:"
+ "msgnum:00000008:"
+ "msgnum:00000009:"
+)
+if [[ "${messages_sorted[*]}" != "${expected_messages[*]}" ]]; then
+ echo "unexpected set of processed messages:"
+ printf '%s\n' "${messages_processed[@]}"
+ echo "contents of $RSYSLOG_OUT_LOG:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/omprog-transactions-failed-messages.sh b/tests/omprog-transactions-failed-messages.sh
new file mode 100755
index 0000000..9d6afd2
--- /dev/null
+++ b/tests/omprog-transactions-failed-messages.sh
@@ -0,0 +1,159 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# This test tests omprog with the confirmMessages=on and useTransactions=on
+# parameters, with the external program returning an error on certain
+# messages.
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary=`echo $srcdir/testsuites/omprog-transactions-bin.sh --failed_messages`
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct" # the default; facilitates sync with the child process
+ queue.dequeueBatchSize="6"
+ confirmMessages="on"
+ useTransactions="on"
+ action.resumeRetryCount="10"
+ action.resumeInterval="1"
+ )
+}
+'
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+
+# Since the transaction boundaries are not deterministic, we cannot check for
+# an exact expected output. We must check the output programmatically.
+
+transaction_state="NONE"
+status_expected=true
+messages_to_commit=()
+messages_processed=()
+line_num=1
+error=
+
+while IFS= read -r line; do
+ if [[ $status_expected == true ]]; then
+ case "$transaction_state" in
+ "NONE")
+ if [[ "$line" != "<= OK" ]]; then
+ error="expecting an OK status from script"
+ break
+ fi
+ ;;
+ "STARTED")
+ if [[ "$line" != "<= OK" ]]; then
+ error="expecting an OK status from script"
+ break
+ fi
+ transaction_state="ACTIVE"
+ ;;
+ "ACTIVE")
+ if [[ "$line" == "<= Error: could not process log message" ]]; then
+ #
+ # TODO: Issue #2420: Deferred messages within a transaction are
+ # not retried by rsyslog.
+ # If that's the expected behavior, what's then the difference
+ # between the RS_RET_OK and the RS_RET_DEFER_COMMIT return codes?
+ # If that's not the expected behavior, the following lines must
+ # be removed when the bug is solved.
+ #
+ # (START OF CODE THAT WILL POSSIBLY NEED TO BE REMOVED)
+ messages_processed+=("${messages_to_commit[@]}")
+ unset "messages_processed[${#messages_processed[@]}-1]"
+ # (END OF CODE THAT WILL POSSIBLY NEED TO BE REMOVED)
+
+ messages_to_commit=()
+ transaction_state="NONE"
+ elif [[ "$line" != "<= DEFER_COMMIT" ]]; then
+ error="expecting a DEFER_COMMIT status from script"
+ break
+ fi
+ ;;
+ "COMMITTED")
+ if [[ "$line" != "<= OK" ]]; then
+ error="expecting an OK status from script"
+ break
+ fi
+ messages_processed+=("${messages_to_commit[@]}")
+ messages_to_commit=()
+ transaction_state="NONE"
+ ;;
+ esac
+ status_expected=false;
+ else
+ if [[ "$line" == "=> BEGIN TRANSACTION" ]]; then
+ if [[ "$transaction_state" != "NONE" ]]; then
+ error="unexpected transaction start"
+ break
+ fi
+ transaction_state="STARTED"
+ elif [[ "$line" == "=> COMMIT TRANSACTION" ]]; then
+ if [[ "$transaction_state" != "ACTIVE" ]]; then
+ error="unexpected transaction commit"
+ break
+ fi
+ transaction_state="COMMITTED"
+ else
+ if [[ "$transaction_state" != "ACTIVE" ]]; then
+ error="unexpected message outside a transaction"
+ break
+ fi
+ if [[ "$line" != "=> msgnum:"* ]]; then
+ error="unexpected message contents"
+ break
+ fi
+ prefix_to_remove="=> "
+ messages_to_commit+=("${line#$prefix_to_remove}")
+ fi
+ status_expected=true;
+ fi
+ ((line_num++))
+done < $RSYSLOG_OUT_LOG
+
+if [[ -z "$error" && "$transaction_state" != "NONE" ]]; then
+ error="unexpected end of file (transaction state: $transaction_state)"
+fi
+
+if [[ -n "$error" ]]; then
+ echo "$RSYSLOG_OUT_LOG: line $line_num: $error"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+# Since the order in which failed messages are retried by rsyslog is not
+# deterministic, we sort the processed messages before checking them.
+IFS=$'\n' messages_sorted=($(sort <<<"${messages_processed[*]}"))
+unset IFS
+
+expected_messages=(
+ "msgnum:00000000:"
+ "msgnum:00000001:"
+ "msgnum:00000002:"
+ "msgnum:00000003:"
+ "msgnum:00000004:"
+ "msgnum:00000005:"
+ "msgnum:00000006:"
+ "msgnum:00000007:"
+ "msgnum:00000008:"
+ "msgnum:00000009:"
+)
+if [[ "${messages_sorted[*]}" != "${expected_messages[*]}" ]]; then
+ echo "unexpected set of processed messages:"
+ printf '%s\n' "${messages_processed[@]}"
+ echo "contents of $RSYSLOG_OUT_LOG:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/omprog-transactions-vg.sh b/tests/omprog-transactions-vg.sh
new file mode 100755
index 0000000..436be23
--- /dev/null
+++ b/tests/omprog-transactions-vg.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# Same test than 'omprog-transactions.sh', but checking for memory
+# problems using valgrind. Note it is not necessary to repeat the
+# rest of checks (this simplifies the maintenance of the tests).
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary=`echo $srcdir/testsuites/omprog-transactions-bin.sh`
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct" # the default; facilitates sync with the child process
+ queue.dequeueBatchSize="6"
+ confirmMessages="on"
+ useTransactions="on"
+ beginTransactionMark="BEGIN TRANSACTION"
+ commitTransactionMark="COMMIT TRANSACTION"
+ action.resumeRetryCount="10"
+ action.resumeInterval="1"
+ )
+}
+'
+startup_vg
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+exit_test
diff --git a/tests/omprog-transactions.sh b/tests/omprog-transactions.sh
new file mode 100755
index 0000000..1937d0f
--- /dev/null
+++ b/tests/omprog-transactions.sh
@@ -0,0 +1,140 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# This test tests omprog with the confirmMessages=on and useTransactions=on
+# parameters, with the external program successfully confirming all messages
+# and transactions.
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omprog/.libs/omprog")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+:msg, contains, "msgnum:" {
+ action(
+ type="omprog"
+ binary=`echo $srcdir/testsuites/omprog-transactions-bin.sh`
+ template="outfmt"
+ name="omprog_action"
+ queue.type="Direct" # the default; facilitates sync with the child process
+ queue.dequeueBatchSize="6"
+ confirmMessages="on"
+ useTransactions="on"
+ beginTransactionMark="BEGIN TRANSACTION"
+ commitTransactionMark="COMMIT TRANSACTION"
+ action.resumeRetryCount="10"
+ action.resumeInterval="1"
+ )
+}
+'
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+
+# Since the transaction boundaries are not deterministic, we cannot check for
+# an exact expected output. We must check the output programmatically.
+
+transaction_state="NONE"
+status_expected=true
+messages_to_commit=()
+messages_processed=()
+line_num=1
+error=
+
+while IFS= read -r line; do
+ if [[ $status_expected == true ]]; then
+ case "$transaction_state" in
+ "NONE")
+ if [[ "$line" != "<= OK" ]]; then
+ error="expecting an OK status from script"
+ break
+ fi
+ ;;
+ "STARTED")
+ if [[ "$line" != "<= OK" ]]; then
+ error="expecting an OK status from script"
+ break
+ fi
+ transaction_state="ACTIVE"
+ ;;
+ "ACTIVE")
+ if [[ "$line" != "<= DEFER_COMMIT" ]]; then
+ error="expecting a DEFER_COMMIT status from script"
+ break
+ fi
+ ;;
+ "COMMITTED")
+ if [[ "$line" != "<= OK" ]]; then
+ error="expecting an OK status from script"
+ break
+ fi
+ messages_processed+=("${messages_to_commit[@]}")
+ messages_to_commit=()
+ transaction_state="NONE"
+ ;;
+ esac
+ status_expected=false;
+ else
+ if [[ "$line" == "=> BEGIN TRANSACTION" ]]; then
+ if [[ "$transaction_state" != "NONE" ]]; then
+ error="unexpected transaction start"
+ break
+ fi
+ transaction_state="STARTED"
+ elif [[ "$line" == "=> COMMIT TRANSACTION" ]]; then
+ if [[ "$transaction_state" != "ACTIVE" ]]; then
+ error="unexpected transaction commit"
+ break
+ fi
+ transaction_state="COMMITTED"
+ else
+ if [[ "$transaction_state" != "ACTIVE" ]]; then
+ error="unexpected message outside a transaction"
+ break
+ fi
+ if [[ "$line" != "=> msgnum:"* ]]; then
+ error="unexpected message contents"
+ break
+ fi
+ prefix_to_remove="=> "
+ messages_to_commit+=("${line#$prefix_to_remove}")
+ fi
+ status_expected=true;
+ fi
+ ((line_num++))
+done < $RSYSLOG_OUT_LOG
+
+if [[ -z "$error" && "$transaction_state" != "NONE" ]]; then
+ error="unexpected end of file (transaction state: $transaction_state)"
+fi
+
+if [[ -n "$error" ]]; then
+ echo "$RSYSLOG_OUT_LOG: line $line_num: $error"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+expected_messages=(
+ "msgnum:00000000:"
+ "msgnum:00000001:"
+ "msgnum:00000002:"
+ "msgnum:00000003:"
+ "msgnum:00000004:"
+ "msgnum:00000005:"
+ "msgnum:00000006:"
+ "msgnum:00000007:"
+ "msgnum:00000008:"
+ "msgnum:00000009:"
+)
+if [[ "${messages_processed[*]}" != "${expected_messages[*]}" ]]; then
+ echo "unexpected set of processed messages:"
+ printf '%s\n' "${messages_processed[@]}"
+ echo "contents of $RSYSLOG_OUT_LOG:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/omrabbitmq_data_1server-vg.sh b/tests/omrabbitmq_data_1server-vg.sh
new file mode 100755
index 0000000..527ab44
--- /dev/null
+++ b/tests/omrabbitmq_data_1server-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/omrabbitmq_data_1server.sh
diff --git a/tests/omrabbitmq_data_1server.sh b/tests/omrabbitmq_data_1server.sh
new file mode 100755
index 0000000..660b5a0
--- /dev/null
+++ b/tests/omrabbitmq_data_1server.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+cmd="./miniamqpsrvr -f $RSYSLOG_DYNNAME.amqp.log -d"
+echo $cmd
+eval $cmd > $RSYSLOG_DYNNAME.source
+if [ ! $? -eq 0 ]; then
+ exit 77
+fi
+
+. $RSYSLOG_DYNNAME.source
+
+generate_conf
+add_conf '
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+template(name="rkTpl" type="string" string="%syslogtag%.%syslogfacility-text%.%syslogpriority-text%")
+# rfc5424 without Timestamp : unable to manage
+template(name="bodyTpl" type="string" string="<%PRI%>1 server %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg:2:$%\n")
+ruleset(name="rmq") {
+ action(type="omrabbitmq" host="localhost" port="'$PORT_AMQP1'" exchange="in"
+ user="mtr" password="mtr" expiration="5000"
+ body_template="bodyTpl" content_type="rfc5424"
+ virtual_host="/metrologie" routing_key_template="rkTpl"
+ populate_properties="on" delivery_mode="transient"
+ )
+}
+if $msg contains "msgrmq" then {
+ call rmq
+}
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg literal "<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=$(printf 'Exchange:in, routing-key:tag.local4.debug, content-type:rfc5424, facility:local4, severity:debug, hostname:172.20.245.8, fromhost:127.0.0.1, delivery-mode:transient, expiration:5000, timestamp:OK, app-id:tag, msg:<167>1 server tag - - - msgrmq')
+echo $EXPECTED | cmp - $RSYSLOG_DYNNAME.amqp.log
+if [ ! $? -eq 0 ]; then
+ echo "Expected:"
+ echo $EXPECTED
+ echo "invalid response generated, $RSYSLOG_DYNNAME.amqp.log is:"
+ cat $RSYSLOG_DYNNAME.amqp.log
+ echo "Rsyslog internal output log:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+content_check "server localhost port"
+exit_test
diff --git a/tests/omrabbitmq_data_2servers.sh b/tests/omrabbitmq_data_2servers.sh
new file mode 100755
index 0000000..1afc616
--- /dev/null
+++ b/tests/omrabbitmq_data_2servers.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+cmd="./miniamqpsrvr -b 1 -f $RSYSLOG_DYNNAME.amqp.log -d"
+echo $cmd
+eval $cmd > $RSYSLOG_DYNNAME.source
+if [ ! $? -eq 0 ]; then
+ exit 77
+fi
+
+. $RSYSLOG_DYNNAME.source
+export OMRABBITMQ_TEST=1
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+template(name="rkTpl" type="string" string="%syslogtag%.%syslogfacility-text%.%syslogpriority-text%")
+# rfc5424 without Timestamp : unable to manage
+template(name="bodyTpl" type="string" string="<%PRI%>1 %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg:2:$%\n")
+ruleset(name="rmq") {
+ action(type="omrabbitmq" host="localhost:'$PORT_AMQP1' localhost:'$PORT_AMQP2'" port="5672"
+ user="mtr" password="mtr" exchange="in" expiration="5000"
+ body_template="bodyTpl" content_type="rfc5424"
+ virtual_host="/metrologie" routing_key_template="rkTpl"
+ populate_properties="on" delivery_mode="transient"
+ )
+}
+if $msg contains "msgrmq" then {
+ call rmq
+}
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg literal "<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED=$(printf 'Exchange:in, routing-key:tag.local4.debug, content-type:rfc5424, facility:local4, severity:debug, hostname:172.20.245.8, fromhost:127.0.0.1, delivery-mode:transient, expiration:5000, timestamp:OK, app-id:tag, msg:<167>1 172.20.245.8 tag - - - msgrmq')
+echo $EXPECTED | cmp - $RSYSLOG_DYNNAME.amqp.log
+if [ ! $? -eq 0 ]; then
+ echo "Expected:"
+ echo $EXPECTED
+ echo "invalid response generated, $RSYSLOG_DYNNAME.amqp.log is:"
+ cat $RSYSLOG_DYNNAME.amqp.log
+ echo "Rsyslog internal output log:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+content_check "server localhost port"
+exit_test
diff --git a/tests/omrabbitmq_error_server0.sh b/tests/omrabbitmq_error_server0.sh
new file mode 100755
index 0000000..9a65420
--- /dev/null
+++ b/tests/omrabbitmq_error_server0.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+cmd="./miniamqpsrvr -b 4 -f $RSYSLOG_DYNNAME.amqp.log -d"
+echo $cmd
+eval $cmd > $RSYSLOG_DYNNAME.source
+if [ ! $? -eq 0 ]; then
+ exit 77
+fi
+
+. $RSYSLOG_DYNNAME.source
+export OMRABBITMQ_TEST=1
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+template(name="rkTpl" type="string" string="%syslogtag%.%syslogfacility-text%.%syslogpriority-text%")
+# rfc5424 without Timestamp : unable to manage
+template(name="bodyTpl" type="string" string="<%PRI%>1 %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg:2:$%\n")
+ruleset(name="rmq") {
+ action(type="omrabbitmq" host="localhost" port="'$PORT_AMQP1'"
+ user="mtr" password="mtr" exchange="in" expiration="5000"
+ exchange_type="topic" durable="off" auto_delete="off"
+ body_template="" content_type="rfc5424"
+ virtual_host="/metrologie" routing_key_template="rkTpl"
+ populate_properties="on" delivery_mode="transient"
+ )
+}
+if $msg contains "msgrmq" then {
+ call rmq
+}
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg literal "<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='Exchange:in, routing-key:tag.local4.debug, content-type:plain/text, facility:local4, severity:debug, hostname:172.20.245.8, fromhost:127.0.0.1, delivery-mode:transient, expiration:5000, timestamp:OK, app-id:tag, msg:<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq'
+cmp_exact $RSYSLOG_DYNNAME.amqp.log
+content_check "exchange declare failed PRECONDITION_FAILED"
+exit_test
diff --git a/tests/omrabbitmq_error_server1.sh b/tests/omrabbitmq_error_server1.sh
new file mode 100755
index 0000000..150374e
--- /dev/null
+++ b/tests/omrabbitmq_error_server1.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+cmd="./miniamqpsrvr -b 2 -f $RSYSLOG_DYNNAME.amqp.log -d"
+echo $cmd
+eval $cmd > $RSYSLOG_DYNNAME.source
+if [ ! $? -eq 0 ]; then
+ exit 77
+fi
+
+. $RSYSLOG_DYNNAME.source
+export OMRABBITMQ_TEST=2000
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+template(name="rkTpl" type="string" string="%syslogtag%.%syslogfacility-text%.%syslogpriority-text%")
+# rfc5424 without Timestamp : unable to manage
+template(name="bodyTpl" type="string" string="<%PRI%>1 %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg:2:$%\n")
+ruleset(name="rmq") {
+ action(type="omrabbitmq" host="localhost:'$PORT_AMQP1' localhost:'$PORT_AMQP2'" port="5672"
+ user="mtr" password="mtr" exchange="in" expiration="5000"
+ exchange_type="topic" durable="on" auto_delete="off"
+ body_template="" content_type="rfc5424"
+ virtual_host="/metrologie" routing_key_template="rkTpl"
+ populate_properties="on" delivery_mode="transient"
+ )
+}
+if $msg contains "msgrmq" then {
+ call rmq
+}
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg literal "<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='Exchange:in, routing-key:tag.local4.debug, content-type:plain/text, facility:local4, severity:debug, hostname:172.20.245.8, fromhost:127.0.0.1, delivery-mode:transient, expiration:5000, timestamp:OK, app-id:tag, msg:<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq'
+cmp_exact $RSYSLOG_DYNNAME.amqp.log
+content_check "disconnected while exchange declare"
+exit_test
diff --git a/tests/omrabbitmq_error_server2.sh b/tests/omrabbitmq_error_server2.sh
new file mode 100755
index 0000000..0f5ebef
--- /dev/null
+++ b/tests/omrabbitmq_error_server2.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+cmd="./miniamqpsrvr -b 3 -f $RSYSLOG_DYNNAME.amqp.log -w 500 -d"
+echo $cmd
+eval $cmd > $RSYSLOG_DYNNAME.source
+if [ ! $? -eq 0 ]; then
+ exit 77
+fi
+
+. $RSYSLOG_DYNNAME.source
+export OMRABBITMQ_TEST=2000
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+template(name="rkTpl" type="string" string="%syslogtag%.%syslogfacility-text%.%syslogpriority-text%")
+# rfc5424 without Timestamp : unable to manage
+template(name="bodyTpl" type="string" string="<%PRI%>1 %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg:2:$%\n")
+ruleset(name="rmq") {
+ action(type="omrabbitmq" host="localhost:'$PORT_AMQP1' localhost:'$PORT_AMQP2'" port="5672"
+ user="mtr" password="mtr" exchange="in" expiration="5000"
+ exchange_type="topic" durable="on" auto_delete="off"
+ body_template="" content_type="rfc5424"
+ virtual_host="/metrologie" routing_key_template="rkTpl"
+ populate_properties="on" delivery_mode="transient"
+ )
+}
+if $msg contains "msgrmq" then {
+ call rmq
+}
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg literal "<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='Exchange:in, routing-key:tag.local4.debug, content-type:plain/text, facility:local4, severity:debug, hostname:172.20.245.8, fromhost:127.0.0.1, delivery-mode:transient, expiration:5000, timestamp:OK, app-id:tag, msg:<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq'
+cmp_exact $RSYSLOG_DYNNAME.amqp.log
+content_check "Connection closed : reconnect"
+exit_test
diff --git a/tests/omrabbitmq_error_server3.sh b/tests/omrabbitmq_error_server3.sh
new file mode 100755
index 0000000..1d47bb1
--- /dev/null
+++ b/tests/omrabbitmq_error_server3.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+cmd="./miniamqpsrvr -b 2 -f $RSYSLOG_DYNNAME.amqp.log -w 500 -d"
+echo $cmd
+eval $cmd > $RSYSLOG_DYNNAME.source
+if [ ! $? -eq 0 ]; then
+ exit 77
+fi
+
+. $RSYSLOG_DYNNAME.source
+export OMRABBITMQ_TEST=2000
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+template(name="rkTpl" type="string" string="%syslogtag%.%syslogfacility-text%.%syslogpriority-text%")
+# rfc5424 without Timestamp : unable to manage
+template(name="bodyTpl" type="string" string="<%PRI%>1 %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg:2:$%\n")
+ruleset(name="rmq") {
+ action(type="omrabbitmq" host="localhost:'$PORT_AMQP1' localhost:'$PORT_AMQP2'" port="5672"
+ user="mtr" password="mtr" exchange="in" expiration="5000"
+ body_template="" content_type="rfc5424"
+ virtual_host="/metrologie" routing_key_template="rkTpl"
+ populate_properties="on" delivery_mode="transient"
+ )
+}
+if $msg contains "msgrmq" then {
+ call rmq
+}
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg literal "<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='Exchange:in, routing-key:tag.local4.debug, content-type:plain/text, facility:local4, severity:debug, hostname:172.20.245.8, fromhost:127.0.0.1, delivery-mode:transient, expiration:5000, timestamp:OK, app-id:tag, msg:<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq'
+cmp_exact $RSYSLOG_DYNNAME.amqp.log
+content_check "Connection closed : reconnect"
+exit_test
diff --git a/tests/omrabbitmq_json.sh b/tests/omrabbitmq_json.sh
new file mode 100755
index 0000000..f8c30bf
--- /dev/null
+++ b/tests/omrabbitmq_json.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+cmd="./miniamqpsrvr -f $RSYSLOG_DYNNAME.amqp.log -d"
+echo $cmd
+eval $cmd > $RSYSLOG_DYNNAME.source
+if [ ! $? -eq 0 ]; then
+ exit 77
+fi
+
+. $RSYSLOG_DYNNAME.source
+export OMRABBITMQ_TEST=1
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+ruleset(name="rmq") {
+ action(type="omrabbitmq" host="localhost" port="'$PORT_AMQP1'"
+ user="mtr" password="mtr" exchange="in" expiration="5000"
+ virtual_host="/metrologie" routing_key="myrouting"
+ )
+}
+if $msg contains "msgrmq" then {
+ call rmq
+}
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg literal "<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq"
+shutdown_when_empty
+wait_shutdown
+expected=$(printf 'Exchange:in, routing-key:myrouting, content-type:application/json, delivery-mode:transient, expiration:5000, msg:{\"message\":\" msgrmq\",\"fromhost\":\"172.20.245.8\",\"facility\":\"local4\",\"priority\":\"debug\",\"timereported\":.*}')
+grep -E "${expected}" $RSYSLOG_DYNNAME.amqp.log > /dev/null 2>&1
+if [ ! $? -eq 0 ]; then
+ echo "Expected:"
+ echo ${expected}
+ echo "invalid response generated, $RSYSLOG_DYNNAME.amqp.log is:"
+ cat $RSYSLOG_DYNNAME.amqp.log
+ echo "Rsyslog internal output log:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+content_check "server localhost port"
+exit_test
diff --git a/tests/omrabbitmq_no_params.sh b/tests/omrabbitmq_no_params.sh
new file mode 100755
index 0000000..79e1e61
--- /dev/null
+++ b/tests/omrabbitmq_no_params.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+action(type="omrabbitmq")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter host must be specified"
+
+exit_test \ No newline at end of file
diff --git a/tests/omrabbitmq_params_invalid0.sh b/tests/omrabbitmq_params_invalid0.sh
new file mode 100755
index 0000000..9732137
--- /dev/null
+++ b/tests/omrabbitmq_params_invalid0.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+action(type="omrabbitmq" exchange="in" routing_key_template="jk" host="host")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "template 'jk' used for routing key does not exist"
+
+exit_test \ No newline at end of file
diff --git a/tests/omrabbitmq_params_invalid1.sh b/tests/omrabbitmq_params_invalid1.sh
new file mode 100755
index 0000000..b09b2e6
--- /dev/null
+++ b/tests/omrabbitmq_params_invalid1.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+action(type="omrabbitmq" exchange="in" routing_key="jk" host="host" body_template="kl")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "template 'kl' used for body does not exist"
+
+exit_test \ No newline at end of file
diff --git a/tests/omrabbitmq_params_invalid2.sh b/tests/omrabbitmq_params_invalid2.sh
new file mode 100755
index 0000000..70b4959
--- /dev/null
+++ b/tests/omrabbitmq_params_invalid2.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+action(type="omrabbitmq" exchange="in" routing_key="jk" host="host" delivery_mode="UNDEF")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "delivery_mode must be TRANSIENT or PERSISTENT"
+
+exit_test \ No newline at end of file
diff --git a/tests/omrabbitmq_params_invalid3.sh b/tests/omrabbitmq_params_invalid3.sh
new file mode 100755
index 0000000..4274dd9
--- /dev/null
+++ b/tests/omrabbitmq_params_invalid3.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+action(type="omrabbitmq" exchange="in" routing_key="jk" host="host" expiration="-1")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter 'expiration' cannot be less than zero"
+
+exit_test
diff --git a/tests/omrabbitmq_params_missing0.sh b/tests/omrabbitmq_params_missing0.sh
new file mode 100755
index 0000000..bb79114
--- /dev/null
+++ b/tests/omrabbitmq_params_missing0.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+action(type="omrabbitmq" host="host" routing_key="jk")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter exchange must be specified"
+
+exit_test \ No newline at end of file
diff --git a/tests/omrabbitmq_params_missing1.sh b/tests/omrabbitmq_params_missing1.sh
new file mode 100755
index 0000000..5def14a
--- /dev/null
+++ b/tests/omrabbitmq_params_missing1.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+action(type="omrabbitmq" exchange="in" host="host")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "routing_key or routing_key_template must be specified"
+
+exit_test \ No newline at end of file
diff --git a/tests/omrabbitmq_params_missing2.sh b/tests/omrabbitmq_params_missing2.sh
new file mode 100755
index 0000000..fcf4654
--- /dev/null
+++ b/tests/omrabbitmq_params_missing2.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-02-26 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+action(type="omrabbitmq" exchange="in" routing_key="jk")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter host must be specified"
+
+exit_test \ No newline at end of file
diff --git a/tests/omrabbitmq_raw.sh b/tests/omrabbitmq_raw.sh
new file mode 100755
index 0000000..6242212
--- /dev/null
+++ b/tests/omrabbitmq_raw.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# add 2019-09-03 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+cmd="./miniamqpsrvr -f $RSYSLOG_DYNNAME.amqp.log -d"
+echo $cmd
+eval $cmd > $RSYSLOG_DYNNAME.source
+if [ ! $? -eq 0 ]; then
+ exit 77
+fi
+
+. $RSYSLOG_DYNNAME.source
+export OMRABBITMQ_TEST=1
+
+generate_conf
+add_conf '
+global(localhostname="server")
+module(load="../contrib/omrabbitmq/.libs/omrabbitmq")
+template(name="rkTpl" type="string" string="%syslogtag%.%syslogfacility-text%.%syslogpriority-text%")
+ruleset(name="rmq") {
+ action(type="omrabbitmq" host="localhost" port="'$PORT_AMQP1'"
+ user="mtr" password="mtr" exchange="in" expiration="5000"
+ exchange_type="topic" durable="off" auto_delete="off"
+ body_template="" content_type="rfc5424"
+ virtual_host="/metrologie" routing_key_template="rkTpl"
+ populate_properties="on" delivery_mode="transient"
+ )
+}
+if $msg contains "msgrmq" then {
+ call rmq
+}
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg literal "<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='Exchange:in, routing-key:tag.local4.debug, content-type:plain/text, facility:local4, severity:debug, hostname:172.20.245.8, fromhost:127.0.0.1, delivery-mode:transient, expiration:5000, timestamp:OK, app-id:tag, msg:<167>Mar 1 01:00:00 172.20.245.8 tag msgrmq'
+cmp_exact $RSYSLOG_DYNNAME.amqp.log
+content_check "server localhost port"
+exit_test
diff --git a/tests/omrelp-invld-tlslib.sh b/tests/omrelp-invld-tlslib.sh
new file mode 100755
index 0000000..56f08ea
--- /dev/null
+++ b/tests/omrelp-invld-tlslib.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# see that we can an error message if wrong tls lib is selected
+# addd 2019-02-09 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+require_relpEngineSetTLSLibByName
+generate_conf
+add_conf '
+module(load="../plugins/omrelp/.libs/omrelp" tls.tlslib="invalid-tlslib-name")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+content_check --regex "omrelp.*invalid-tlslib-name.*not accepted"
+exit_test
diff --git a/tests/omrelp_dflt_port.c b/tests/omrelp_dflt_port.c
new file mode 100644
index 0000000..4734057
--- /dev/null
+++ b/tests/omrelp_dflt_port.c
@@ -0,0 +1,9 @@
+#include "config.h"
+#include <stdio.h>
+
+int
+main(int __attribute__((unused)) argc, char * __attribute__((unused)) argv[])
+{
+ printf("%s", RELP_DFLT_PT);
+ return 0;
+}
diff --git a/tests/omrelp_errmsg_no_connect.sh b/tests/omrelp_errmsg_no_connect.sh
new file mode 100755
index 0000000..dc45d12
--- /dev/null
+++ b/tests/omrelp_errmsg_no_connect.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# add 2018-11-14 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+# note: we "abuse" TCPFLOOD_PORT a bit as we already have it assigned
+# the core fact is that nobody is listening on it.
+add_conf '
+module(load="../plugins/omrelp/.libs/omrelp")
+action(type="omrelp" target="127.0.0.1" port="'$TCPFLOOD_PORT'")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+content_check "could not connect to remote server"
+exit_test
diff --git a/tests/omrelp_wrong_authmode.sh b/tests/omrelp_wrong_authmode.sh
new file mode 100755
index 0000000..2165faa
--- /dev/null
+++ b/tests/omrelp_wrong_authmode.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# add 2018-09-13 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omrelp/.libs/omrelp")
+
+ruleset(name="ruleset") {
+ action(type="omrelp" target="127.0.0.1" port="'$TCPFLOOD_PORT'"
+ tls="on" tls.authMode="INVALID_AUTH_MODE" tls.caCert="tls-certs/ca.pem"
+ tls.myCert="tls-certs/cert.pem" tls.myPrivKey="tls-certs/key.pem"
+ tls.permittedPeer=["rsyslog-test-root-ca"])
+}
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "omrelp.* invalid auth.*mode .*INVALID_AUTH_MODE"
+exit_test
diff --git a/tests/omruleset-queue.sh b/tests/omruleset-queue.sh
new file mode 100755
index 0000000..937af4a
--- /dev/null
+++ b/tests/omruleset-queue.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# test for omruleset. What we do is have the main queue forward
+# all messages to a secondary ruleset via omruleset, which then does
+# the actual file write. We check if all messages arrive at the file,
+# what implies that omruleset works. No filters or special queue modes
+# are used, but the ruleset uses its own queue. So we can also inject
+# more messages without running into troubles.
+# added 2009-11-02 by rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo \[omruleset-queue.sh\]: test for omruleset functionality with a ruleset queue
+
+uname
+if [ $(uname) = "SunOS" ] ; then
+ echo "This test currently does not work on all flavors of Solaris."
+ exit 77
+fi
+
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=20000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+$ModLoad ../plugins/omruleset/.libs/omruleset
+
+$ruleset rsinclude
+# create ruleset main queue with default parameters
+$RulesetCreateMainQueue on
+# make sure we do not terminate too early!
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+
+$ruleset RSYSLOG_DefaultRuleset
+$ActionOmrulesetRulesetName rsinclude
+*.* :omruleset:
+'
+startup
+injectmsg
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/omruleset.sh b/tests/omruleset.sh
new file mode 100755
index 0000000..3a92888
--- /dev/null
+++ b/tests/omruleset.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Basic test for omruleset. What we do is have the main queue forward
+# all messages to a secondary ruleset via omruleset, which then does
+# the actual file write. We check if all messages arrive at the file,
+# what implies that omruleset works. No filters or special queue modes
+# are used, so the message is re-enqueued into the main message queue.
+# We inject just 5,000 message because we may otherwise run into
+# queue full conditions (as we use the same queue) and that
+# would result in longer execution time. In any case, 5000 messages
+# are well enough to test what we want to test.
+# added 2009-11-02 by rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+$ModLoad ../plugins/omruleset/.libs/omruleset
+
+$ruleset rsinclude
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+
+$ruleset RSYSLOG_DefaultRuleset
+$ActionOmrulesetRulesetName rsinclude
+*.* :omruleset:
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/omsnmp_errmsg_no_params.sh b/tests/omsnmp_errmsg_no_params.sh
new file mode 100755
index 0000000..ec8512e
--- /dev/null
+++ b/tests/omsnmp_errmsg_no_params.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# add 2018-09-25 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%\n")
+
+module(load="../plugins/omsnmp/.libs/omsnmp")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+action(type="omsnmp")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter 'server' required but not specified"
+
+exit_test
diff --git a/tests/omstdout-basic.sh b/tests/omstdout-basic.sh
new file mode 100755
index 0000000..4ac4046
--- /dev/null
+++ b/tests/omstdout-basic.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omstdout/.libs/omstdout")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="-%msg%-\n")
+action(type="omstdout" template="outfmt")
+
+'
+startup > $RSYSLOG_OUT_LOG
+tcpflood -m1
+shutdown_when_empty
+wait_shutdowna
+
+grep "msgnum:00000000:" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/omtcl.sh b/tests/omtcl.sh
new file mode 100755
index 0000000..9fa3617
--- /dev/null
+++ b/tests/omtcl.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$ModLoad ../contrib/omtcl/.libs/omtcl
+$template tcldict, "message \"%msg:::json%\" fromhost \"%HOSTNAME:::json%\" facility \"%syslogfacility-text%\" priority \"%syslogpriority-text%\" timereported \"%timereported:::date-rfc3339%\" timegenerated \"%timegenerated:::date-rfc3339%\" raw \"%rawmsg:::json%\" tag \"%syslogtag:::json%\""
+'
+add_conf "*.* :omtcl:$srcdir/omtcl.tcl,doAction;tcldict
+"
+startup
+echo 'injectmsg literal <167>Mar 1 01:00:00 172.20.245.8 tag hello world' | \
+ ./diagtalker -p$IMDIAG_PORT || error_exit $?
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check 'HELLO WORLD'
+cat $RSYSLOG_OUT_LOG
+exit_test
diff --git a/tests/omtcl.tcl b/tests/omtcl.tcl
new file mode 100644
index 0000000..ff12251
--- /dev/null
+++ b/tests/omtcl.tcl
@@ -0,0 +1,9 @@
+proc doAction {msg} {
+ set fd [open $::env(RSYSLOG_OUT_LOG) a]
+ puts $fd "message processed:"
+ foreach {k v} $msg {
+ puts $fd " $k: <<$v>>"
+ }
+ puts $fd " uppercase message: <<[string toupper [dict get $msg message]]>>"
+ close $fd
+}
diff --git a/tests/omudpspoof_errmsg_no_params.sh b/tests/omudpspoof_errmsg_no_params.sh
new file mode 100755
index 0000000..a14ffb6
--- /dev/null
+++ b/tests/omudpspoof_errmsg_no_params.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# add 2019-04-15 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omudpspoof/.libs/omudpspoof")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+action(type="omudpspoof")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter 'target' required but not specified"
+
+exit_test
diff --git a/tests/omusrmsg-errmsg-no-params.sh b/tests/omusrmsg-errmsg-no-params.sh
new file mode 100755
index 0000000..d6e4354
--- /dev/null
+++ b/tests/omusrmsg-errmsg-no-params.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+# add 2019-08-05 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+action(type="omusrmsg")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "parameter 'users' required but not specified"
+exit_test
diff --git a/tests/omusrmsg-noabort-vg.sh b/tests/omusrmsg-noabort-vg.sh
new file mode 100755
index 0000000..c9437ed
--- /dev/null
+++ b/tests/omusrmsg-noabort-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/omusrmsg-noabort.sh
diff --git a/tests/omusrmsg-noabort.sh b/tests/omusrmsg-noabort.sh
new file mode 100755
index 0000000..352414c
--- /dev/null
+++ b/tests/omusrmsg-noabort.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# same as omusrmsg-noabort, but with legacy syntax.
+# addd 2018-08-05 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" {
+ action(type="omusrmsg" users="nouser" template="outfmt")
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+ }
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+# while we cannot check if the messages arrived in user sessions, we
+# can check that all messages arrive in the file, which we consider as
+# an indication that everything went well.
+seq_check
+exit_test
diff --git a/tests/operatingstate-basic.sh b/tests/operatingstate-basic.sh
new file mode 100755
index 0000000..0204dbd
--- /dev/null
+++ b/tests/operatingstate-basic.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# added 2018-10-24 by Rainer Gerhards
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(operatingStateFile="'$RSYSLOG_DYNNAME.osf'")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+action(type="invalid-type")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+check_file_not_exists "$RSYSLOG_DYNNAME.osf.previous"
+check_file_exists "$RSYSLOG_DYNNAME.osf"
+content_check "invalid-type" "$RSYSLOG_DYNNAME.osf"
+content_check "CLEAN CLOSE" "$RSYSLOG_DYNNAME.osf"
+exit_test
diff --git a/tests/operatingstate-empty.sh b/tests/operatingstate-empty.sh
new file mode 100755
index 0000000..29d9fa3
--- /dev/null
+++ b/tests/operatingstate-empty.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# added 2018-10-24 by Rainer Gerhards
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(operatingStateFile="'$RSYSLOG_DYNNAME.osf'")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+# create an unclean file
+err_osf_content=""
+printf '%s' "$err_osf_content" > $RSYSLOG_DYNNAME.osf
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+check_file_exists "$RSYSLOG_DYNNAME.osf.previous"
+check_file_exists "$RSYSLOG_DYNNAME.osf"
+content_check "this may be an indication of a problem, e.g. empty file" "$RSYSLOG_OUT_LOG"
+content_check "CLEAN CLOSE" "$RSYSLOG_DYNNAME.osf"
+exit_test
diff --git a/tests/operatingstate-unclean.sh b/tests/operatingstate-unclean.sh
new file mode 100755
index 0000000..30b3443
--- /dev/null
+++ b/tests/operatingstate-unclean.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# added 2018-10-24 by Rainer Gerhards
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(operatingStateFile="'$RSYSLOG_DYNNAME.osf'")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+# create an unclean file
+err_osf_content="20180924-160109: STATE INITIALIZING 8.39.0.master
+20180924-160110: STATE"
+printf '%s\n' "$err_osf_content" > $RSYSLOG_DYNNAME.osf
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+check_file_exists "$RSYSLOG_DYNNAME.osf.previous"
+export EXPECTED="$err_osf_content"
+cmp_exact "$RSYSLOG_DYNNAME.osf.previous"
+check_file_exists "$RSYSLOG_DYNNAME.osf"
+content_check "does not end with 'CLEAN CLOSE, instead it has '0110: STATE'" "$RSYSLOG_OUT_LOG"
+content_check "CLEAN CLOSE" "$RSYSLOG_DYNNAME.osf"
+exit_test
diff --git a/tests/ourtail.c b/tests/ourtail.c
new file mode 100644
index 0000000..c31babb
--- /dev/null
+++ b/tests/ourtail.c
@@ -0,0 +1,46 @@
+/* This is a quick and dirty "tail implementation", one which always
+ * skips the first line, but nothing else. I have done this to prevent
+ * the various incompatible options of tail come into my way. One could
+ * probably work around this by using autoconf magic, but for me it
+ * was much quicker writing this small C program, which really should
+ * be portable across all platforms.
+ *
+ * Part of the testbench for rsyslog.
+ *
+ * Copyright 2009 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>
+
+int main(int __attribute__((unused)) argc, char __attribute__((unused)) *argv[])
+{
+ int c;
+
+ for(c = getchar() ; c != EOF && c != '\n' ; c = getchar())
+ /*skip to newline*/;
+
+ if(c == '\n')
+ c = getchar();
+
+ for( ; c != EOF ; c = getchar())
+ putchar(c);
+
+ return 0;
+}
diff --git a/tests/override_getaddrinfo.c b/tests/override_getaddrinfo.c
new file mode 100644
index 0000000..32bbafe
--- /dev/null
+++ b/tests/override_getaddrinfo.c
@@ -0,0 +1,28 @@
+// we need this for dlsym(): #include <dlfcn.h>
+#include "config.h"
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+int getaddrinfo(const char *node __attribute__((unused)),
+ const char *service __attribute__((unused)),
+ const struct addrinfo *hints __attribute__((unused)),
+ struct addrinfo **res __attribute__((unused)))
+{
+ return EAI_MEMORY;
+}
+
+static void __attribute__((constructor))
+my_init(void)
+{
+ /* we currently do not need this entry point, but keep it as
+ * a "template". It can be used, e.g. to emit some diagnostic
+ * information:
+ printf("loaded\n");
+ * or - more importantly - obtain a pointer to the overriden
+ * API:
+ orig_etry = dlsym(RTLD_NEXT, "original_entry_point");
+ */
+}
diff --git a/tests/override_gethostname.c b/tests/override_gethostname.c
new file mode 100644
index 0000000..10a4867
--- /dev/null
+++ b/tests/override_gethostname.c
@@ -0,0 +1,22 @@
+// we need this for dlsym(): #include <dlfcn.h>
+#include <stdio.h>
+
+
+int gethostname(char *name, size_t __attribute__((unused)) len)
+{
+ *name = '\0';
+ return 0;
+}
+
+static void __attribute__((constructor))
+my_init(void)
+{
+ /* we currently do not need this entry point, but keep it as
+ * a "template". It can be used, e.g. to emit some diagnostic
+ * information:
+ printf("loaded\n");
+ * or - more importantly - obtain a pointer to the overriden
+ * API:
+ orig_etry = dlsym(RTLD_NEXT, "original_entry_point");
+ */
+}
diff --git a/tests/override_gethostname_nonfqdn.c b/tests/override_gethostname_nonfqdn.c
new file mode 100644
index 0000000..5f53857
--- /dev/null
+++ b/tests/override_gethostname_nonfqdn.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int gethostname(char *name, size_t __attribute__((unused)) len)
+{
+ *name++ = 'n';
+ *name++ = 'o';
+ *name++ = 'n';
+ *name++ = 'f';
+ *name++ = 'q';
+ *name++ = 'd';
+ *name++ = 'n';
+ *name++ = '\0';
+ return 0;
+}
diff --git a/tests/parsertest-parse-3164-buggyday-udp.sh b/tests/parsertest-parse-3164-buggyday-udp.sh
new file mode 100755
index 0000000..9dcd4c0
--- /dev/null
+++ b/tests/parsertest-parse-3164-buggyday-udp.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp:::date-rfc3164-buggyday%,%hostname%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<38> Mar 7 19:06:53 example tag: testmessage (only date actually tested)\""
+tcpflood -m1 -T "udp" -M "\"<38> Mar 17 19:06:53 example tag: testmessage (only date actually tested)\""
+shutdown_when_empty
+wait_shutdown
+
+echo '38,auth,info,Mar 07 19:06:53,example,tag,tag:, testmessage (only date actually tested)
+38,auth,info,Mar 17 19:06:53,example,tag,tag:, testmessage (only date actually tested)' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/parsertest-parse-3164-buggyday.sh b/tests/parsertest-parse-3164-buggyday.sh
new file mode 100755
index 0000000..1b0af13
--- /dev/null
+++ b/tests/parsertest-parse-3164-buggyday.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp:::date-rfc3164-buggyday%,%hostname%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<38> Mar 7 19:06:53 example tag: testmessage (only date actually tested)\""
+tcpflood -m1 -M "\"<38> Mar 17 19:06:53 example tag: testmessage (only date actually tested)\""
+shutdown_when_empty
+wait_shutdown
+
+echo '38,auth,info,Mar 07 19:06:53,example,tag,tag:, testmessage (only date actually tested)
+38,auth,info,Mar 17 19:06:53,example,tag,tag:, testmessage (only date actually tested)' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/parsertest-parse-nodate-udp.sh b/tests/parsertest-parse-nodate-udp.sh
new file mode 100755
index 0000000..1e36544
--- /dev/null
+++ b/tests/parsertest-parse-nodate-udp.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+setvar_RS_HOSTNAME
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%hostname%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<27>xapi: [error|xen3|15|Guest liveness monitor D:bca30ab3f1c1|master_connection] Connection to master died. I will continue to retry indefinitely (suppressing future logging of this message)\""
+tcpflood -m1 -T "udp" -M "\"This is a message!\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="27,daemon,err,$RS_HOSTNAME,xapi,xapi:, [error|xen3|15|Guest liveness monitor D:bca30ab3f1c1|master_connection] Connection to master died. I will continue to retry indefinitely (suppressing future logging of this message)
+13,user,notice,This,is,is, a message!"
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/parsertest-parse-nodate.sh b/tests/parsertest-parse-nodate.sh
new file mode 100755
index 0000000..2264d9b
--- /dev/null
+++ b/tests/parsertest-parse-nodate.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+setvar_RS_HOSTNAME
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%hostname%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<27>xapi: [error|xen3|15|Guest liveness monitor D:bca30ab3f1c1|master_connection] Connection to master died. I will continue to retry indefinitely (suppressing future logging of this message)\""
+tcpflood -m1 -M "\"This is a message!\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="27,daemon,err,$RS_HOSTNAME,xapi,xapi:, [error|xen3|15|Guest liveness monitor D:bca30ab3f1c1|master_connection] Connection to master died. I will continue to retry indefinitely (suppressing future logging of this message)
+13,user,notice,This,is,is, a message!"
+cmp_exact $RSYSLOG_OUT_LOG
+exit_test
diff --git a/tests/parsertest-parse1-udp.sh b/tests/parsertest-parse1-udp.sh
new file mode 100755
index 0000000..7280583
--- /dev/null
+++ b/tests/parsertest-parse1-udp.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+setvar_RS_HOSTNAME
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+global(localHostname="localhost")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp%,%hostname%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: UDP request discarded from SERVER1/2741 to test_app:255.255.255.255/61601\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 27 19:06:53 source_server sshd(pam_unix)[12750]: session opened for user foo by (uid=0)\""
+tcpflood -m1 -T "udp" -M "\"<167>Apr 6 15:07:10 lxcvs07 sshd(pam_unix)[31738]: session closed for user cvsadmin\""
+tcpflood -m1 -T "udp" -M "\"<167>Jul 31 21:39:21 example-b example-gw[10538]: disconnect host=/192.0.2.1 destination=192.0.2.2/11282 in=3274 out=1448 duration=0\""
+tcpflood -m1 -T "udp" -M "\"<167>AUG 10 22:18:24 host tag This msg contains 8-bit European chars: äöü\""
+tcpflood -m1 -T "udp" -M "\"<167> Mar 7 19:06:53 example tag: testmessage (only date actually tested)\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 7 2008 19:06:53: example tag: testmessage (only date actually tested)\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 7 2008 19:06:53 example tag: testmessage (only date actually tested)\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 7 19:06:53: example tag: testmessage (only date actually tested)\""
+tcpflood -m1 -T "udp" -M "\"<14>Jan 6 2009 15:22:26 localhost\""
+tcpflood -m1 -T "udp" -M "\"<167>Oct 8 23:05:06 10.321.1.123 05\\\",result_code=200,b\""
+tcpflood -m1 -T "udp" -M "\"<167>Feb 18 16:01:59 serverX -- MARK --\""
+tcpflood -m1 -T "udp" -M "\"Feb 18 16:01:59 serverX -- MARK --\""
+tcpflood -m1 -T "udp" -M "\"<38>Mar 27 19:06:53 source_server 0123456789012345678901234567890123456789: MSG part\""
+tcpflood -m1 -T "udp" -M "\"<29>Oct 16 20:47:24 example-p exam-pl[12345]: connect host= /192.0.2.1\""
+tcpflood -m1 -T "udp" -M "\"<34>Oct 11 22:14:15 mymachine su: su root failed for lonvick on /dev/pts/8\""
+tcpflood -m1 -T "udp" -M "\"<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - BOMsu root failed for lonvick on /dev/pts/8\""
+tcpflood -m1 -T "udp" -M "\"<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 myproc 8710 - - %% Its time to make the do-nuts.\""
+tcpflood -m1 -T "udp" -M "\"<165>1 2003-10-11T22:14:15.003Z mymachine.example.com evntslog - ID47 [exampleSDID@32473 iut=\\\"3\\\" eventSource= \\\"Application\\\" eventID=\\\"1011\\\"][examplePriority@32473 class=\\\"high\\\"]\""
+tcpflood -m1 -T "udp" -M "\"<165>1 2003-10-11T22:14:15.003Z mymachine.example.com evntslog - ID47 [exampleSDID@32473 iut=\\\"3\\\" eventSource= \\\"Application\\\" eventID=\\\"1011\\\"] BOMAn application event log entry...\""
+tcpflood -m1 -T "udp" -M "\"<6>AUG 10 22:18:24 2009 netips-warden2-p [audit] user=[*SMS] src=192.168.11.11 iface=5 access=9 Update State Reset\""
+tcpflood -m1 -T "udp" -M "\"<14>Aug 30 23:00:05 X4711 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\""
+tcpflood -m1 -T "udp" -M "\"<14>Aug 30 23:00:05 X4711 \""
+tcpflood -m1 -T "udp" -M "\"<14>Aug 30 23:00:05 X4711\""
+tcpflood -m1 -T "udp" -M "\"<14>Aug 30 23:00:05 \""
+tcpflood -m1 -T "udp" -M "\"<14>Aug 30 23:00:05\""
+tcpflood -m1 -T "udp" -M "\"<14>2010-08-30T23:00:05Z X4711 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\""
+tcpflood -m1 -T "udp" -M "\"<14>2010-08-30T23:00:05Z X4711 \""
+tcpflood -m1 -T "udp" -M "\"<14>2010-08-30T23:00:05Z X4711\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="167,local4,debug,Mar 6 16:57:54,172.20.245.8,%PIX-7-710005,%PIX-7-710005:, UDP request discarded from SERVER1/2741 to test_app:255.255.255.255/61601
+167,local4,debug,Mar 27 19:06:53,source_server,sshd(pam_unix),sshd(pam_unix)[12750]:, session opened for user foo by (uid=0)
+167,local4,debug,Apr 6 15:07:10,lxcvs07,sshd(pam_unix),sshd(pam_unix)[31738]:, session closed for user cvsadmin
+167,local4,debug,Jul 31 21:39:21,example-b,example-gw,example-gw[10538]:, disconnect host=/192.0.2.1 destination=192.0.2.2/11282 in=3274 out=1448 duration=0
+167,local4,debug,Aug 10 22:18:24,host,tag,tag, This msg contains 8-bit European chars: äöü
+167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested)
+167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested)
+167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested)
+167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested)
+14,user,info,Jan 6 15:22:26,localhost,,,
+167,local4,debug,Oct 8 23:05:06,10.321.1.123,05\",result_code=200,b,05\",result_code=200,b,
+167,local4,debug,Feb 18 16:01:59,serverX,--,--, MARK --
+13,user,notice,Feb 18 16:01:59,serverX,--,--, MARK --
+38,auth,info,Mar 27 19:06:53,source_server,0123456789012345678901234567890123456789,0123456789012345678901234567890123456789:, MSG part
+29,daemon,notice,Oct 16 20:47:24,example-p,exam-pl,exam-pl[12345]:, connect host= /192.0.2.1
+34,auth,crit,Oct 11 22:14:15,mymachine,su,su:, su root failed for lonvick on /dev/pts/8
+34,auth,crit,Oct 11 22:14:15,mymachine.example.com,su,su,BOMsu root failed for lonvick on /dev/pts/8
+165,local4,notice,Aug 24 05:14:15,192.0.2.1,myproc,myproc[8710],%% Its time to make the do-nuts.
+165,local4,notice,Oct 11 22:14:15,mymachine.example.com,evntslog,evntslog,
+165,local4,notice,Oct 11 22:14:15,mymachine.example.com,evntslog,evntslog,BOMAn application event log entry...
+6,kern,info,Aug 10 22:18:24,2009,,, netips-warden2-p [audit] user=[*SMS] src=192.168.11.11 iface=5 access=9 Update State Reset
+14,user,info,Aug 30 23:00:05,X4711,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,
+14,user,info,Aug 30 23:00:05,X4711,,,
+14,user,info,Aug 30 23:00:05,X4711,,,
+14,user,info,Aug 30 23:00:05,$RS_HOSTNAME,,,
+14,user,info,Aug 30 23:00:05,$RS_HOSTNAME,,,
+14,user,info,Aug 30 23:00:05,X4711,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,
+14,user,info,Aug 30 23:00:05,X4711,,,
+14,user,info,Aug 30 23:00:05,X4711,,,"
+cmp_exact $RSYSLOG_OUT_LOG
+exit_test
diff --git a/tests/parsertest-parse1.sh b/tests/parsertest-parse1.sh
new file mode 100755
index 0000000..8c81440
--- /dev/null
+++ b/tests/parsertest-parse1.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+setvar_RS_HOSTNAME
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp%,%hostname%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: UDP request discarded from SERVER1/2741 to test_app:255.255.255.255/61601\""
+tcpflood -m1 -M "\"<167>Mar 27 19:06:53 source_server sshd(pam_unix)[12750]: session opened for user foo by (uid=0)\""
+tcpflood -m1 -M "\"<167>Apr 6 15:07:10 lxcvs07 sshd(pam_unix)[31738]: session closed for user cvsadmin\""
+tcpflood -m1 -M "\"<167>Jul 31 21:39:21 example-b example-gw[10538]: disconnect host=/192.0.2.1 destination=192.0.2.2/11282 in=3274 out=1448 duration=0\""
+tcpflood -m1 -M "\"<167>AUG 10 22:18:24 host tag This msg contains 8-bit European chars: äöü\""
+tcpflood -m1 -M "\"<167> Mar 7 19:06:53 example tag: testmessage (only date actually tested)\""
+tcpflood -m1 -M "\"<167>Mar 7 2008 19:06:53: example tag: testmessage (only date actually tested)\""
+tcpflood -m1 -M "\"<167>Mar 7 2008 19:06:53 example tag: testmessage (only date actually tested)\""
+tcpflood -m1 -M "\"<167>Mar 7 19:06:53: example tag: testmessage (only date actually tested)\""
+tcpflood -m1 -M "\"<14>Jan 6 2009 15:22:26 localhost\""
+tcpflood -m1 -M "\"<167>Oct 8 23:05:06 10.321.1.123 05\\\",result_code=200,b\""
+tcpflood -m1 -M "\"<167>Feb 18 16:01:59 serverX -- MARK --\""
+tcpflood -m1 -M "\"Feb 18 16:01:59 serverX -- MARK --\""
+tcpflood -m1 -M "\"<38>Mar 27 19:06:53 source_server 0123456789012345678901234567890123456789: MSG part\""
+tcpflood -m1 -M "\"<29>Oct 16 20:47:24 example-p exam-pl[12345]: connect host= /192.0.2.1\""
+tcpflood -m1 -M "\"<34>Oct 11 22:14:15 mymachine su: su root failed for lonvick on /dev/pts/8\""
+tcpflood -m1 -M "\"<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - BOMsu root failed for lonvick on /dev/pts/8\""
+tcpflood -m1 -M "\"<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 myproc 8710 - - %% Its time to make the do-nuts.\""
+tcpflood -m1 -M "\"<165>1 2003-10-11T22:14:15.003Z mymachine.example.com evntslog - ID47 [exampleSDID@32473 iut=\\\"3\\\" eventSource= \\\"Application\\\" eventID=\\\"1011\\\"][examplePriority@32473 class=\\\"high\\\"]\""
+tcpflood -m1 -M "\"<165>1 2003-10-11T22:14:15.003Z mymachine.example.com evntslog - ID47 [exampleSDID@32473 iut=\\\"3\\\" eventSource= \\\"Application\\\" eventID=\\\"1011\\\"] BOMAn application event log entry...\""
+tcpflood -m1 -M "\"<6>AUG 10 22:18:24 2009 netips-warden2-p [audit] user=[*SMS] src=192.168.11.11 iface=5 access=9 Update State Reset\""
+tcpflood -m1 -M "\"<14>Aug 30 23:00:05 X4711 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\""
+tcpflood -m1 -M "\"<14>Aug 30 23:00:05 X4711 \""
+tcpflood -m1 -M "\"<14>Aug 30 23:00:05 X4711\""
+tcpflood -m1 -M "\"<14>Aug 30 23:00:05 \""
+tcpflood -m1 -M "\"<14>Aug 30 23:00:05\""
+tcpflood -m1 -M "\"<14>2010-08-30T23:00:05Z X4711 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\""
+tcpflood -m1 -M "\"<14>2010-08-30T23:00:05Z X4711 \""
+tcpflood -m1 -M "\"<14>2010-08-30T23:00:05Z X4711\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="167,local4,debug,Mar 6 16:57:54,172.20.245.8,%PIX-7-710005,%PIX-7-710005:, UDP request discarded from SERVER1/2741 to test_app:255.255.255.255/61601
+167,local4,debug,Mar 27 19:06:53,source_server,sshd(pam_unix),sshd(pam_unix)[12750]:, session opened for user foo by (uid=0)
+167,local4,debug,Apr 6 15:07:10,lxcvs07,sshd(pam_unix),sshd(pam_unix)[31738]:, session closed for user cvsadmin
+167,local4,debug,Jul 31 21:39:21,example-b,example-gw,example-gw[10538]:, disconnect host=/192.0.2.1 destination=192.0.2.2/11282 in=3274 out=1448 duration=0
+167,local4,debug,Aug 10 22:18:24,host,tag,tag, This msg contains 8-bit European chars: äöü
+167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested)
+167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested)
+167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested)
+167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested)
+14,user,info,Jan 6 15:22:26,localhost,,,
+167,local4,debug,Oct 8 23:05:06,10.321.1.123,05\",result_code=200,b,05\",result_code=200,b,
+167,local4,debug,Feb 18 16:01:59,serverX,--,--, MARK --
+13,user,notice,Feb 18 16:01:59,serverX,--,--, MARK --
+38,auth,info,Mar 27 19:06:53,source_server,0123456789012345678901234567890123456789,0123456789012345678901234567890123456789:, MSG part
+29,daemon,notice,Oct 16 20:47:24,example-p,exam-pl,exam-pl[12345]:, connect host= /192.0.2.1
+34,auth,crit,Oct 11 22:14:15,mymachine,su,su:, su root failed for lonvick on /dev/pts/8
+34,auth,crit,Oct 11 22:14:15,mymachine.example.com,su,su,BOMsu root failed for lonvick on /dev/pts/8
+165,local4,notice,Aug 24 05:14:15,192.0.2.1,myproc,myproc[8710],%% Its time to make the do-nuts.
+165,local4,notice,Oct 11 22:14:15,mymachine.example.com,evntslog,evntslog,
+165,local4,notice,Oct 11 22:14:15,mymachine.example.com,evntslog,evntslog,BOMAn application event log entry...
+6,kern,info,Aug 10 22:18:24,2009,,, netips-warden2-p [audit] user=[*SMS] src=192.168.11.11 iface=5 access=9 Update State Reset
+14,user,info,Aug 30 23:00:05,X4711,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,
+14,user,info,Aug 30 23:00:05,X4711,,,
+14,user,info,Aug 30 23:00:05,X4711,,,
+14,user,info,Aug 30 23:00:05,$RS_HOSTNAME,,,
+14,user,info,Aug 30 23:00:05,$RS_HOSTNAME,,,
+14,user,info,Aug 30 23:00:05,X4711,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,
+14,user,info,Aug 30 23:00:05,X4711,,,
+14,user,info,Aug 30 23:00:05,X4711,,,"
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/parsertest-parse2-udp.sh b/tests/parsertest-parse2-udp.sh
new file mode 100755
index 0000000..2be7c3f
--- /dev/null
+++ b/tests/parsertest-parse2-udp.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+global(localHostname="localhost")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<175>Oct 16 23:47:31 #001 MSWinEventLog 0#011Security#01119023582#011Fri Oct 16 16:30:44 2009#011592#011Security#011rgabcde#011User#011Success Audit#011XSXSXSN01#011Detailed Tracking#011#0112572#01119013885\""
+shutdown_when_empty
+wait_shutdown
+
+echo '175,local5,debug,Oct 16 23:47:31,#001,#001, MSWinEventLog 0#011Security#01119023582#011Fri Oct 16 16:30:44 2009#011592#011Security#011rgabcde#011User#011Success Audit#011XSXSXSN01#011Detailed Tracking#011#0112572#01119013885' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/parsertest-parse2.sh b/tests/parsertest-parse2.sh
new file mode 100755
index 0000000..75bb819
--- /dev/null
+++ b/tests/parsertest-parse2.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+global(localHostname="localhost")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<175>Oct 16 23:47:31 #001 MSWinEventLog 0#011Security#01119023582#011Fri Oct 16 16:30:44 2009#011592#011Security#011rgabcde#011User#011Success Audit#011XSXSXSN01#011Detailed Tracking#011#0112572#01119013885\""
+shutdown_when_empty
+wait_shutdown
+
+echo '175,local5,debug,Oct 16 23:47:31,#001,#001, MSWinEventLog 0#011Security#01119023582#011Fri Oct 16 16:30:44 2009#011592#011Security#011rgabcde#011User#011Success Audit#011XSXSXSN01#011Detailed Tracking#011#0112572#01119013885' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/parsertest-parse3-udp.sh b/tests/parsertest-parse3-udp.sh
new file mode 100755
index 0000000..f36d178
--- /dev/null
+++ b/tests/parsertest-parse3-udp.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+
+template(name="outfmt" type="string" string="%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")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<175>Oct 16 2009 23:47:31 hostname tag This is a message\""
+tcpflood -m1 -T "udp" -M "\"<175>Oct 16 2009 23:47:31 hostname tag[1234] This is a message\""
+shutdown_when_empty
+wait_shutdown
+
+echo '"2009-10-16T23:47:31", "hostname", "tag", "", "7", " This is a message"
+"2009-10-16T23:47:31", "hostname", "tag", "1234", "7", " This is a message"' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/parsertest-parse3.sh b/tests/parsertest-parse3.sh
new file mode 100755
index 0000000..f824a08
--- /dev/null
+++ b/tests/parsertest-parse3.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+
+template(name="outfmt" type="string" string="%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")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<175>Oct 16 2009 23:47:31 hostname tag This is a message\""
+tcpflood -m1 -M "\"<175>Oct 16 2009 23:47:31 hostname tag[1234] This is a message\""
+shutdown_when_empty
+wait_shutdown
+
+echo '"2009-10-16T23:47:31", "hostname", "tag", "", "7", " This is a message"
+"2009-10-16T23:47:31", "hostname", "tag", "1234", "7", " This is a message"' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/parsertest-parse_8bit_escape-udp.sh b/tests/parsertest-parse_8bit_escape-udp.sh
new file mode 100755
index 0000000..6ec1e44
--- /dev/null
+++ b/tests/parsertest-parse_8bit_escape-udp.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2018-06-28 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+$Escape8BitCharactersOnReceive on
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp%,%hostname%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<6>AUG 10 22:18:24 host tag This msg contains 8-bit European chars: äöü\""
+shutdown_when_empty
+wait_shutdown
+
+echo '6,kern,info,Aug 10 22:18:24,host,tag,tag, This msg contains 8-bit European chars: #303#244#303#266#303#274' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/parsertest-parse_8bit_escape.sh b/tests/parsertest-parse_8bit_escape.sh
new file mode 100755
index 0000000..fd8e694
--- /dev/null
+++ b/tests/parsertest-parse_8bit_escape.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# add 2018-06-28 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+$Escape8BitCharactersOnReceive on
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp%,%hostname%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<6>AUG 10 22:18:24 host tag This msg contains 8-bit European chars: äöü\""
+shutdown_when_empty
+wait_shutdown
+
+echo '6,kern,info,Aug 10 22:18:24,host,tag,tag, This msg contains 8-bit European chars: #303#244#303#266#303#274' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/parsertest-parse_invld_regex-udp.sh b/tests/parsertest-parse_invld_regex-udp.sh
new file mode 100755
index 0000000..5e4b819
--- /dev/null
+++ b/tests/parsertest-parse_invld_regex-udp.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# add 2018-06-28 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+
+template(name="outfmt" type="string" string="%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")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<175>Feb 08 2008 23:47:31 hostname tag This is a message\""
+shutdown_when_empty
+wait_shutdown
+
+echo '"2008-02-08T23:47:31", "hostname", "tag", **NO MATCH** **BAD REGULAR EXPRESSION**, "7", " This is a message"' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/parsertest-parse_invld_regex.sh b/tests/parsertest-parse_invld_regex.sh
new file mode 100755
index 0000000..cd8e790
--- /dev/null
+++ b/tests/parsertest-parse_invld_regex.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# add 2018-06-28 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+
+template(name="outfmt" type="string" string="%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")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<175>Feb 08 2008 23:47:31 hostname tag This is a message\""
+shutdown_when_empty
+wait_shutdown
+
+echo '"2008-02-08T23:47:31", "hostname", "tag", **NO MATCH** **BAD REGULAR EXPRESSION**, "7", " This is a message"' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/parsertest-snare_ccoff_udp.sh b/tests/parsertest-snare_ccoff_udp.sh
new file mode 100755
index 0000000..4c7f435
--- /dev/null
+++ b/tests/parsertest-snare_ccoff_udp.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+setvar_RS_HOSTNAME
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+$EscapeControlCharactersOnReceive off
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%hostname%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"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\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="13,user,notice,$RS_HOSTNAME,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\n"
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/parsertest-snare_ccoff_udp2.sh b/tests/parsertest-snare_ccoff_udp2.sh
new file mode 100755
index 0000000..dd51bec
--- /dev/null
+++ b/tests/parsertest-snare_ccoff_udp2.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+setvar_RS_HOSTNAME
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+$EscapeControlCharactersOnReceive off
+
+template(name="outfmt" type="string" string="insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (%msg:::space-cc%, %syslogfacility%, %HOSTNAME%,%syslogpriority%, 20100321185328, 20100321185328, %iut%, %syslogtag:::space-cc%)\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"test\""
+tcpflood -m1 -T "udp" -M "\"UX=Abcd-efg-hij-klmno; XXXXX=1111111111, Z123=192.12.231.245:11111, S1234=123456789, XXXXXX=111111111\""
+tcpflood -m1 -T "udp" -M "\"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\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (, 1, test,5, 20100321185328, 20100321185328, 1, )
+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, $RS_HOSTNAME,5, 20100321185328, 20100321185328, 1, UX=Abcd-efg-hij-klmno;)
+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\n, 1, $RS_HOSTNAME,5, 20100321185328, 20100321185328, 1, windowsserver MSWinEventLog 1 Security 1167 Fri)"
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/perctile-simple-vg.sh b/tests/perctile-simple-vg.sh
new file mode 100755
index 0000000..b868564
--- /dev/null
+++ b/tests/perctile-simple-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/perctile-simple.sh
diff --git a/tests/perctile-simple.sh b/tests/perctile-simple.sh
new file mode 100755
index 0000000..b3bca04
--- /dev/null
+++ b/tests/perctile-simple.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+. ${srcdir:=.}/diag.sh init
+DELIMITER='|'
+BUCKETNAME='test_bucket'
+STATNAME='test_stat_name'
+# uncomment to test really long statname
+#STATNAME='123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" Ruleset="stats" bracketing="on")
+#module(load="../plugins/impstats/.libs/impstats" format="json" interval="1" severity="7" Ruleset="stats" bracketing="on")
+template(name="outfmt" type="string" string="%$.timestamp% %msg% val=%$.val%\n")
+
+percentile_stats(name="'$BUCKETNAME'"
+ percentiles=["95", "50", "99"]
+ windowsize="1000"
+ delimiter="'${DELIMITER}'"
+ )
+
+if $msg startswith " msgnum:" then {
+ # test with a small window
+ set $.val = field($msg, 58, 2);
+ set $.status = percentile_observe("'$BUCKETNAME'", "'$STATNAME'", $.val);
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+. $srcdir/diag.sh block-stats-flush
+shuf -i 1-1000 | sed -e 's/^/injectmsg literal <167>Mar 1 01:00:00 172.20.245.8 tag msgnum:/g' | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+wait_queueempty
+. $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it
+
+shuf -i 1001-2000 | sed -e 's/^/injectmsg literal <167>Mar 1 01:00:00 172.20.245.8 tag msgnum:/g' | $TESTTOOL_DIR/diagtalker -p$IMDIAG_PORT || error_exit $?
+. $srcdir/diag.sh await-stats-flush-after-block
+wait_queueempty
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+
+echo doing shutdown
+shutdown_when_empty
+custom_content_check "${STATNAME}${DELIMITER}p95=950" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}p50=500" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}p99=990" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}window_min=1" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}window_max=1000" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}window_sum=500500" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}window_count=1000" "${RSYSLOG_DYNNAME}.out.stats.log"
+
+custom_content_check "${STATNAME}${DELIMITER}p95=1950" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}p50=1500" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}p99=1990" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}window_min=1001" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}window_max=2000" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}window_sum=1500500" "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_content_check "${STATNAME}${DELIMITER}window_count=1000" "${RSYSLOG_DYNNAME}.out.stats.log"
+
+exit_test
diff --git a/tests/pgsql-actq-mt-withpause-vg.sh b/tests/pgsql-actq-mt-withpause-vg.sh
new file mode 100755
index 0000000..b431123
--- /dev/null
+++ b/tests/pgsql-actq-mt-withpause-vg.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+module(load="../plugins/ompgsql/.libs/ompgsql")
+if $msg contains "msgnum" then {
+ action(type="ompgsql" server="127.0.0.1"
+ db="syslogtest" user="postgres" pass="testbench"
+ queue.size="10000" queue.type="linkedList"
+ queue.workerthreads="5"
+ queue.workerthreadMinimumMessages="500"
+ queue.timeoutWorkerthreadShutdown="1000"
+ queue.timeoutEnqueue="10000"
+ )
+}'
+startup_vg
+injectmsg 0 50000
+wait_queueempty
+echo waiting for worker threads to timeout
+./msleep 3000
+injectmsg 50000 50000
+wait_queueempty
+echo waiting for worker threads to timeout
+./msleep 2000
+injectmsg 100000 50000
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-msg.sql -t -A > $RSYSLOG_OUT_LOG
+seq_check 0 149999
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pgsql-actq-mt-withpause.sh b/tests/pgsql-actq-mt-withpause.sh
new file mode 100755
index 0000000..37d6e47
--- /dev/null
+++ b/tests/pgsql-actq-mt-withpause.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+module(load="../plugins/ompgsql/.libs/ompgsql")
+if $msg contains "msgnum" then {
+ action(type="ompgsql" server="127.0.0.1"
+ db="syslogtest" user="postgres" pass="testbench"
+ queue.size="10000" queue.type="linkedList"
+ queue.workerthreads="5"
+ queue.workerthreadMinimumMessages="500"
+ queue.timeoutWorkerthreadShutdown="1000"
+ queue.timeoutEnqueue="10000"
+ )
+}'
+startup
+injectmsg 0 50000
+wait_queueempty
+echo waiting for worker threads to timeout
+./msleep 3000
+injectmsg 50000 50000
+wait_queueempty
+echo waiting for worker threads to timeout
+./msleep 2000
+injectmsg 100000 50000
+shutdown_when_empty
+wait_shutdown
+
+psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-msg.sql -t -A > $RSYSLOG_OUT_LOG
+seq_check 0 149999
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pgsql-basic-cnf6-vg.sh b/tests/pgsql-basic-cnf6-vg.sh
new file mode 100755
index 0000000..af28f86
--- /dev/null
+++ b/tests/pgsql-basic-cnf6-vg.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+module(load="../plugins/ompgsql/.libs/ompgsql")
+if $msg contains "msgnum" then {
+ action(type="ompgsql" server="127.0.0.1"
+ db="syslogtest" user="postgres" pass="testbench")
+}'
+startup_vg
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-msg.sql -t -A > $RSYSLOG_OUT_LOG
+seq_check 0 4999
+
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pgsql-basic-cnf6.sh b/tests/pgsql-basic-cnf6.sh
new file mode 100755
index 0000000..5ab2975
--- /dev/null
+++ b/tests/pgsql-basic-cnf6.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+module(load="../plugins/ompgsql/.libs/ompgsql")
+if $msg contains "msgnum" then {
+ action(type="ompgsql" server="127.0.0.1"
+ db="syslogtest" user="postgres" pass="testbench")
+}'
+startup
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown
+
+
+psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-msg.sql -t -A > $RSYSLOG_OUT_LOG
+
+seq_check 0 4999
+
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pgsql-basic-threads-cnf6.sh b/tests/pgsql-basic-threads-cnf6.sh
new file mode 100755
index 0000000..68d288b
--- /dev/null
+++ b/tests/pgsql-basic-threads-cnf6.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+module(load="../plugins/ompgsql/.libs/ompgsql")
+if $msg contains "msgnum" then {
+ action(type="ompgsql"
+ server="127.0.0.1" db="syslogtest"
+ user="postgres" pass="testbench"
+ queue.workerthreads="4" )
+}'
+startup
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown
+
+
+psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-msg.sql -t -A > $RSYSLOG_OUT_LOG
+
+seq_check 0 4999
+
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pgsql-basic-vg.sh b/tests/pgsql-basic-vg.sh
new file mode 100755
index 0000000..0b38b89
--- /dev/null
+++ b/tests/pgsql-basic-vg.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+$ModLoad ../plugins/ompgsql/.libs/ompgsql
+:msg, contains, "msgnum:" :ompgsql:127.0.0.1,syslogtest,postgres,testbench
+'
+startup_vg
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-msg.sql -t -A > $RSYSLOG_OUT_LOG
+seq_check 0 4999
+
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pgsql-basic.sh b/tests/pgsql-basic.sh
new file mode 100755
index 0000000..78ef217
--- /dev/null
+++ b/tests/pgsql-basic.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+$ModLoad ../plugins/ompgsql/.libs/ompgsql
+:msg, contains, "msgnum:" :ompgsql:127.0.0.1,syslogtest,postgres,testbench
+'
+startup
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown
+
+psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-msg.sql -t -A > $RSYSLOG_OUT_LOG
+seq_check 0 4999
+
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pgsql-template-cnf6-vg.sh b/tests/pgsql-template-cnf6-vg.sh
new file mode 100755
index 0000000..5886654
--- /dev/null
+++ b/tests/pgsql-template-cnf6-vg.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+template(name="pgtemplate" type="list" option.sql="on") {
+ constant(value="INSERT INTO SystemEvents (SysLogTag) values ('"'"'")
+ property(name="msg")
+ constant(value="'"'"')")
+}
+
+module(load="../plugins/ompgsql/.libs/ompgsql")
+if $msg contains "msgnum" then {
+ action(type="ompgsql" server="127.0.0.1"
+ db="syslogtest" user="postgres" pass="testbench"
+ template="pgtemplate")
+}'
+
+startup_vg
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+# we actually put the message in the SysLogTag field, so we know it doesn't use the default
+# template, like in pgsql-basic
+psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-syslogtag.sql -t -A > $RSYSLOG_OUT_LOG
+
+seq_check 0 4999
+
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pgsql-template-cnf6.sh b/tests/pgsql-template-cnf6.sh
new file mode 100755
index 0000000..9a0a00d
--- /dev/null
+++ b/tests/pgsql-template-cnf6.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f ${srcdir}/testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+template(name="pgtemplate" type="list" option.sql="on") {
+ constant(value="INSERT INTO SystemEvents (SysLogTag) values ('"'"'")
+ property(name="msg")
+ constant(value="'"'"')")
+}
+
+module(load="../plugins/ompgsql/.libs/ompgsql")
+if $msg contains "msgnum" then {
+ action(type="ompgsql" server="127.0.0.1"
+ db="syslogtest" user="postgres" pass="testbench"
+ template="pgtemplate")
+}'
+
+startup
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown
+
+
+psql -h localhost -U postgres -d syslogtest -f ${srcdir}/testsuites/pgsql-select-syslogtag.sql -t -A > $RSYSLOG_OUT_LOG
+
+
+seq_check 0 4999
+
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pgsql-template-threads-cnf6.sh b/tests/pgsql-template-threads-cnf6.sh
new file mode 100755
index 0000000..99ece41
--- /dev/null
+++ b/tests/pgsql-template-threads-cnf6.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+template(name="pgtemplate" type="list" option.sql="on") {
+ constant(value="INSERT INTO SystemEvents (SysLogTag) values ('"'"'")
+ property(name="msg")
+ constant(value="'"'"')")
+}
+
+module(load="../plugins/ompgsql/.libs/ompgsql")
+if $msg contains "msgnum" then {
+ action(type="ompgsql" server="127.0.0.1"
+ db="syslogtest" user="postgres" pass="testbench"
+ template="pgtemplate" queue.workerthreads="4")
+}'
+
+startup
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown
+
+
+psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-syslogtag.sql -t -A > $RSYSLOG_OUT_LOG
+
+seq_check 0 4999
+
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pgsql-template-vg.sh b/tests/pgsql-template-vg.sh
new file mode 100755
index 0000000..de36039
--- /dev/null
+++ b/tests/pgsql-template-vg.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+# putting the message in the SyslogTag field, so we know the template is actually used
+$template mytemplate,"insert into SystemEvents (SysLogTag) values '
+add_conf "('%msg%')"
+add_conf '",STDSQL
+
+$ModLoad ../plugins/ompgsql/.libs/ompgsql
+:msg, contains, "msgnum:" :ompgsql:127.0.0.1,syslogtest,postgres,testbench;mytemplate
+'
+startup_vg
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-syslogtag.sql -t -A > $RSYSLOG_OUT_LOG
+seq_check 0 4999
+
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pgsql-template.sh b/tests/pgsql-template.sh
new file mode 100755
index 0000000..13e345c
--- /dev/null
+++ b/tests/pgsql-template.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under GPLv3
+
+. ${srcdir:=.}/diag.sh init
+
+psql -h localhost -U postgres -f testsuites/pgsql-basic.sql
+
+generate_conf
+add_conf '
+# putting the message in the SyslogTag field, so we know the template is actually used
+$template mytemplate,"insert into SystemEvents (SysLogTag) values '
+add_conf "('%msg%')"
+add_conf '",STDSQL
+
+$ModLoad ../plugins/ompgsql/.libs/ompgsql
+:msg, contains, "msgnum:" :ompgsql:127.0.0.1,syslogtest,postgres,testbench;mytemplate
+'
+startup
+injectmsg 0 5000
+shutdown_when_empty
+wait_shutdown
+
+# we actually put the message in the SysLogTag field, so we know it doesn't use the default
+# template, like in pgsql-basic
+psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-syslogtag.sql -t -A > $RSYSLOG_OUT_LOG
+
+seq_check 0 4999
+
+echo cleaning up test database
+psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;'
+
+exit_test
diff --git a/tests/pipe_noreader.sh b/tests/pipe_noreader.sh
new file mode 100755
index 0000000..ca1274d
--- /dev/null
+++ b/tests/pipe_noreader.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# This is test driver for a pipe that has no reader. This mimics a usual
+# real-world scenario, the /dev/xconsole pipe. Some versions of rsyslog
+# were known to hang or loop on this pipe, thus we added this scenario
+# as a permanent testcase. For some details, please see bug tracker
+# http://bugzilla.adiscon.com/show_bug.cgi?id=186
+#
+# IMPORTANT: we do NOT check any result message set. The whole point in
+# this test is to verify that we do NOT run into an eternal loop. As such,
+# the test is "PASS", if rsyslogd terminates. If it does not terminate, we
+# obviously do not cause "FAIL", but processing will hang, which should be
+# a good-enough indication of failure.
+#
+# added 2010-04-26 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="log"
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" |./'$RSYSLOG_DYNNAME'.pipe
+'
+mkfifo ./$RSYSLOG_DYNNAME.pipe
+startup
+# we need to emit ~ 128K of data according to bug report
+tcpflood -m1000 -d500
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+# NO need to check seqno -- see header comment
+echo we did not loop, so the test is successful
+exit_test
diff --git a/tests/pipeaction.sh b/tests/pipeaction.sh
new file mode 100755
index 0000000..a50784e
--- /dev/null
+++ b/tests/pipeaction.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# Test for the pipe output action.
+# will create a fifo in the current directory, write to it and
+# then do the usual sequence checks.
+# added 2009-11-05 by RGerhards
+
+# create the pipe and start a background process that copies data from
+# it to the "regular" work file
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=20000
+generate_conf
+add_conf '
+$MainMsgQueueTimeoutShutdown 10000
+
+# set spool locations and switch queue to disk-only mode
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+$MainMsgQueueFilename mainq
+$MainMsgQueueType disk
+
+$template outfmt,"%msg:F,58:2%\n"
+# with pipes, we do not need to use absolute path names, so
+# we can simply refer to our working pipe via the usual relative
+# path name
+:msg, contains, "msgnum:" |rsyslog-testbench-fifo;outfmt
+'
+rm -f rsyslog-testbench-fifo
+mkfifo rsyslog-testbench-fifo
+cp rsyslog-testbench-fifo $RSYSLOG_OUT_LOG &
+CPPROCESS=$!
+echo background cp process id is $CPPROCESS
+
+# now do the usual run
+startup
+injectmsg 0 $NUMMESSAGES
+shutdown_when_empty
+wait_shutdown
+
+# wait for the cp process to finish, do pipe-specific cleanup
+echo waiting for background cp to terminate...
+wait $CPPROCESS
+rm -f rsyslog-testbench-fifo
+echo background cp has terminated, continue test...
+
+# and continue the usual checks
+seq_check
+exit_test
diff --git a/tests/pmdb2diag_parse.sh b/tests/pmdb2diag_parse.sh
new file mode 100755
index 0000000..db24faa
--- /dev/null
+++ b/tests/pmdb2diag_parse.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# add 2019-03-09 by Philippe Duveau, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imfile/.libs/imfile")
+module(load="../contrib/pmdb2diag/.libs/pmdb2diag")
+input(type="imfile" ruleset="ruleset" tag="in:"
+ File="./'$RSYSLOG_DYNNAME'.crio.input"
+ Startmsg.regex="^[0-9]{4}-[0-9]{2}-[0-9]{2}"
+ Escapelf="on" needparse="on")
+template(name="test" type="string" string="time: %TIMESTAMP:::date-rfc3339%, level: %syslogseverity-text%, app: %app-name%, procid: %procid% msg: %msg%\n")
+parser(type="pmdb2diag" timeformat="%Y-%m-%d-%H.%M.%S." timepos="0" levelpos="59" pidstarttoprogstartshift="49" name="db2.diag.cust")
+ruleset(name="ruleset" parser="db2.diag.cust") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="test")
+}
+'
+{
+ echo '2015-05-06-16.53.26.989430+120 E1876227378A1702 LEVEL: Critical'
+ echo 'PID : 4390941 TID : 89500 PROC : db2sysc 0'
+ echo 'INSTANCE: db2itst NODE : 000 DB : DBTST'
+ echo '2015-05-06-16.53.26.989440+120 E1876227378A1702 LEVEL: Alert'
+ echo 'PID : 4390942 TID : 89500 PROC : db2sysc 0'
+ echo 'INSTANCE: db2itst NODE : 000 DB : DBTST'
+ echo '2015-05-06-16.53.26.989450+120 E1876227378A1702 LEVEL: Severe'
+ echo 'PID : 4390943 TID : 89500 PROC : db2sysc 0'
+ echo 'INSTANCE: db2itst NODE : 000 DB : DBTST'
+ echo '2015-05-06-16.53.26.989460+120 E1876227378A1702 LEVEL: Error'
+ echo 'PID : 4390944 TID : 89500 PROC : db2sysc 0'
+ echo 'INSTANCE: db2itst NODE : 000 DB : DBTST'
+ echo '2015-05-06-16.53.26.989470+120 E1876227378A1702 LEVEL: Warning'
+ echo 'PID : 4390945 TID : 89500 PROC : db2sysc 0'
+ echo 'INSTANCE: db2itst NODE : 000 DB : DBTST'
+ echo '2015-05-06-16.53.26.989480+120 E1876227378A1702 LEVEL: Event'
+ echo 'PID : 4390946 TID : 89500 PROC : db2sysc 0'
+ echo 'INSTANCE: db2itst NODE : 000 DB : DBTST'
+ echo '2015-05-06-16.53.26.989490+120 E1876227378A1702 LEVEL: Info'
+ echo 'PID : 4390947 TID : 89500 PROC : db2sysc 0'
+ echo 'INSTANCE: db2itst NODE : 000 DB : DBTST'
+ echo '2015-05-06-16.53.26.989500+120 E1876227378A1702 LEVEL: Debug'
+ echo 'PID : 4390948 TID : 89500 PROC : db2sysc 0'
+ echo 'INSTANCE: db2itst NODE : 000 DB : DBTST'
+ echo '2015-05-06-16.53.26.989510+120 E1876227378A1702 LEVEL: Info'
+} > $RSYSLOG_DYNNAME.crio.input
+startup
+shutdown_when_empty
+wait_shutdown
+cmp - $RSYSLOG_OUT_LOG <<!end
+time: 2015-05-06T16:53:26.989430+02:00, level: emerg, app: db2sysc, procid: 4390941 msg: 2015-05-06-16.53.26.989430+120 E1876227378A1702 LEVEL: Critical\nPID : 4390941 TID : 89500 PROC : db2sysc 0\nINSTANCE: db2itst NODE : 000 DB : DBTST
+time: 2015-05-06T16:53:26.989440+02:00, level: alert, app: db2sysc, procid: 4390942 msg: 2015-05-06-16.53.26.989440+120 E1876227378A1702 LEVEL: Alert\nPID : 4390942 TID : 89500 PROC : db2sysc 0\nINSTANCE: db2itst NODE : 000 DB : DBTST
+time: 2015-05-06T16:53:26.989450+02:00, level: crit, app: db2sysc, procid: 4390943 msg: 2015-05-06-16.53.26.989450+120 E1876227378A1702 LEVEL: Severe\nPID : 4390943 TID : 89500 PROC : db2sysc 0\nINSTANCE: db2itst NODE : 000 DB : DBTST
+time: 2015-05-06T16:53:26.989460+02:00, level: err, app: db2sysc, procid: 4390944 msg: 2015-05-06-16.53.26.989460+120 E1876227378A1702 LEVEL: Error\nPID : 4390944 TID : 89500 PROC : db2sysc 0\nINSTANCE: db2itst NODE : 000 DB : DBTST
+time: 2015-05-06T16:53:26.989470+02:00, level: warning, app: db2sysc, procid: 4390945 msg: 2015-05-06-16.53.26.989470+120 E1876227378A1702 LEVEL: Warning\nPID : 4390945 TID : 89500 PROC : db2sysc 0\nINSTANCE: db2itst NODE : 000 DB : DBTST
+time: 2015-05-06T16:53:26.989480+02:00, level: notice, app: db2sysc, procid: 4390946 msg: 2015-05-06-16.53.26.989480+120 E1876227378A1702 LEVEL: Event\nPID : 4390946 TID : 89500 PROC : db2sysc 0\nINSTANCE: db2itst NODE : 000 DB : DBTST
+time: 2015-05-06T16:53:26.989490+02:00, level: info, app: db2sysc, procid: 4390947 msg: 2015-05-06-16.53.26.989490+120 E1876227378A1702 LEVEL: Info\nPID : 4390947 TID : 89500 PROC : db2sysc 0\nINSTANCE: db2itst NODE : 000 DB : DBTST
+time: 2015-05-06T16:53:26.989500+02:00, level: debug, app: db2sysc, procid: 4390948 msg: 2015-05-06-16.53.26.989500+120 E1876227378A1702 LEVEL: Debug\nPID : 4390948 TID : 89500 PROC : db2sysc 0\nINSTANCE: db2itst NODE : 000 DB : DBTST
+!end
+
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmlastmsg-udp.sh b/tests/pmlastmsg-udp.sh
new file mode 100755
index 0000000..5a64e89
--- /dev/null
+++ b/tests/pmlastmsg-udp.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/pmlastmsg/.libs/pmlastmsg")
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+ruleset(name="ruleset1" parser=["rsyslog.lastline","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<13>last message repeated 5 times\""
+tcpflood -m1 -T "udp" -M "\"<13>last message repeated 0090909787348927349875 times\""
+tcpflood -m1 -T "udp" -M "\"<13>last message repeated 5 times\""
+tcpflood -m1 -T "udp" -M "\"<13>last message repeated 5 times -- more data\""
+tcpflood -m1 -T "udp" -M "\"<13>last message repeated 5.2 times\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG long message ================================================================================\""
+tcpflood -m1 -T "udp" -M "\"<34>1 2003-11-11T22:14:15.003Z mymachine.example.com su - ID47 last message repeated 5 times\""
+shutdown_when_empty
+wait_shutdown
+
+echo 'last message repeated 5 times
+last message repeated 0090909787348927349875 times
+ repeated 5 times
+ repeated 5 times -- more data
+ repeated 5.2 times
+ Rest of message...
+ long message ================================================================================
+last message repeated 5 times' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmlastmsg.sh b/tests/pmlastmsg.sh
new file mode 100755
index 0000000..ed44b58
--- /dev/null
+++ b/tests/pmlastmsg.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/pmlastmsg/.libs/pmlastmsg")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+ruleset(name="ruleset1" parser=["rsyslog.lastline","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<13>last message repeated 5 times\""
+tcpflood -m1 -M "\"<13>last message repeated 0090909787348927349875 times\""
+tcpflood -m1 -M "\"<13>last message repeated 5 times\""
+tcpflood -m1 -M "\"<13>last message repeated 5 times -- more data\""
+tcpflood -m1 -M "\"<13>last message repeated 5.2 times\""
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...\""
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG long message ================================================================================\""
+tcpflood -m1 -M "\"<34>1 2003-11-11T22:14:15.003Z mymachine.example.com su - ID47 last message repeated 5 times\""
+shutdown_when_empty
+wait_shutdown
+
+echo 'last message repeated 5 times
+last message repeated 0090909787348927349875 times
+ repeated 5 times
+ repeated 5 times -- more data
+ repeated 5.2 times
+ Rest of message...
+ long message ================================================================================
+last message repeated 5 times' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmnormalize-basic-vg.sh b/tests/pmnormalize-basic-vg.sh
new file mode 100755
index 0000000..9696ba8
--- /dev/null
+++ b/tests/pmnormalize-basic-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# added 2019-04-10 by Rainer Gerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/pmnormalize-basic.sh
diff --git a/tests/pmnormalize-basic.sh b/tests/pmnormalize-basic.sh
new file mode 100755
index 0000000..7ca2b96
--- /dev/null
+++ b/tests/pmnormalize-basic.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# add 2016-12-08 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/pmnormalize/.libs/pmnormalize")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset")
+parser(name="custom.pmnormalize" type="pmnormalize" rulebase="'$srcdir'/testsuites/pmnormalize_basic.rulebase")
+
+template(name="test" type="string" string="host: %hostname%, ip: %fromhost-ip%, tag: %syslogtag%, pri: %pri%, syslogfacility: %syslogfacility%, syslogseverity: %syslogseverity% msg: %msg%\n")
+
+ruleset(name="ruleset" parser="custom.pmnormalize") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="test")
+}
+'
+startup
+tcpflood -m1 -M "\"<189> ubuntu tag1: is no longer listening on 127.0.0.1 test\""
+tcpflood -m1 -M "\"<112> debian tag2: is no longer listening on 255.255.255.255 test\""
+tcpflood -m1 -M "\"<177> centos tag3: is no longer listening on 192.168.0.9 test\""
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='host: ubuntu, ip: 127.0.0.1, tag: tag1, pri: 189, syslogfacility: 23, syslogseverity: 5 msg: test
+host: debian, ip: 255.255.255.255, tag: tag2, pri: 112, syslogfacility: 14, syslogseverity: 0 msg: test
+host: centos, ip: 192.168.0.9, tag: tag3, pri: 177, syslogfacility: 22, syslogseverity: 1 msg: test'
+cmp_exact
+
+exit_test
diff --git a/tests/pmnormalize-invld-rulebase-vg.sh b/tests/pmnormalize-invld-rulebase-vg.sh
new file mode 100755
index 0000000..f3d4311
--- /dev/null
+++ b/tests/pmnormalize-invld-rulebase-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# added 2019-04-10 by Rainer Gerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/pmnormalize-invld-rulebase.sh
diff --git a/tests/pmnormalize-invld-rulebase.sh b/tests/pmnormalize-invld-rulebase.sh
new file mode 100755
index 0000000..48102bc
--- /dev/null
+++ b/tests/pmnormalize-invld-rulebase.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# add 2016-12-08 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/pmnormalize/.libs/pmnormalize")
+parser(name="custom.pmnormalize" type="pmnormalize" rulebase="DOES-NOT-EXIST")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "cannot open rulebase .*DOES-NOT-EXIST"
+
+exit_test
diff --git a/tests/pmnormalize-neither_rule_rulebase-vg.sh b/tests/pmnormalize-neither_rule_rulebase-vg.sh
new file mode 100755
index 0000000..d5e76ee
--- /dev/null
+++ b/tests/pmnormalize-neither_rule_rulebase-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# added 2019-04-10 by Rainer Gerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/pmnormalize-neither_rule_rulebase.sh
diff --git a/tests/pmnormalize-neither_rule_rulebase.sh b/tests/pmnormalize-neither_rule_rulebase.sh
new file mode 100755
index 0000000..091165d
--- /dev/null
+++ b/tests/pmnormalize-neither_rule_rulebase.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# add 2019-04-10 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/pmnormalize/.libs/pmnormalize")
+parser(name="custom.pmnormalize" type="pmnormalize")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "pmnormalize:.*you need to specify either"
+
+exit_test
diff --git a/tests/pmnormalize-rule-vg.sh b/tests/pmnormalize-rule-vg.sh
new file mode 100755
index 0000000..25d33bc
--- /dev/null
+++ b/tests/pmnormalize-rule-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# added 2019-04-10 by Rainer Gerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/pmnormalize-rule.sh
diff --git a/tests/pmnormalize-rule.sh b/tests/pmnormalize-rule.sh
new file mode 100755
index 0000000..f7cdbf3
--- /dev/null
+++ b/tests/pmnormalize-rule.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# add 2017-06-12 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/pmnormalize/.libs/pmnormalize")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset")
+parser(name="custom.pmnormalize" type="pmnormalize" rule=["rule=:<%pri:number%> %fromhost-ip:ipv4% %hostname:word% %syslogtag:char-to:\\x3a%: %msg:rest%", "rule=:<%pri:number%> %hostname:word% %fromhost-ip:ipv4% %syslogtag:char-to:\\x3a%: %msg:rest%"])
+
+template(name="test" type="string" string="host: %hostname%, ip: %fromhost-ip%, tag: %syslogtag%, pri: %pri%, syslogfacility: %syslogfacility%, syslogseverity: %syslogseverity% msg: %msg%\n")
+
+ruleset(name="ruleset" parser="custom.pmnormalize") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="test")
+}
+'
+startup
+tcpflood -m1 -M "\"<189> 127.0.0.1 ubuntu tag1: this is a test message\""
+tcpflood -m1 -M "\"<112> 255.255.255.255 debian tag2: this is a test message\""
+tcpflood -m1 -M "\"<177> centos 192.168.0.9 tag3: this is a test message\""
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='host: ubuntu, ip: 127.0.0.1, tag: tag1, pri: 189, syslogfacility: 23, syslogseverity: 5 msg: this is a test message
+host: debian, ip: 255.255.255.255, tag: tag2, pri: 112, syslogfacility: 14, syslogseverity: 0 msg: this is a test message
+host: centos, ip: 192.168.0.9, tag: tag3, pri: 177, syslogfacility: 22, syslogseverity: 1 msg: this is a test message'
+cmp_exact
+
+exit_test
diff --git a/tests/pmnormalize-rule_and_rulebase-vg.sh b/tests/pmnormalize-rule_and_rulebase-vg.sh
new file mode 100755
index 0000000..b848b07
--- /dev/null
+++ b/tests/pmnormalize-rule_and_rulebase-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# added 2019-04-10 by Rainer Gerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/pmnormalize-rule_and_rulebase.sh
diff --git a/tests/pmnormalize-rule_and_rulebase.sh b/tests/pmnormalize-rule_and_rulebase.sh
new file mode 100755
index 0000000..9e9ee73
--- /dev/null
+++ b/tests/pmnormalize-rule_and_rulebase.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# add 2019-04-10 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/pmnormalize/.libs/pmnormalize")
+parser(name="custom.pmnormalize" type="pmnormalize" rule="" rulebase="")
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "pmnormalize:.*you need to specify one of"
+
+exit_test
diff --git a/tests/pmnormalize-rule_invld-data-vg.sh b/tests/pmnormalize-rule_invld-data-vg.sh
new file mode 100755
index 0000000..6c49a9a
--- /dev/null
+++ b/tests/pmnormalize-rule_invld-data-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# added 2019-04-10 by Rainer Gerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/pmnormalize-rule_invld-data.sh
diff --git a/tests/pmnormalize-rule_invld-data.sh b/tests/pmnormalize-rule_invld-data.sh
new file mode 100755
index 0000000..039c402
--- /dev/null
+++ b/tests/pmnormalize-rule_invld-data.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2019-04-10 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/pmnormalize/.libs/pmnormalize")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset")
+parser(name="custom.pmnormalize" type="pmnormalize" undefinedPropertyError="on"
+ rule="rule=:<%pri:number%> %fromhost-ip:ipv4% %hostname:word% %syslogtag:char-to:\\x3a%: %msg:rest%")
+
+template(name="test" type="string" string="%msg%\n")
+
+ruleset(name="ruleset" parser="custom.pmnormalize") {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="test")
+}
+action(type="omfile" file="'$RSYSLOG_DYNNAME'.othermsg")
+'
+startup
+tcpflood -m1 -M "\"<abc> 127.0.0.1 ubuntu tag1: this is a test message\""
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='<abc> 127.0.0.1 ubuntu tag1: this is a test message'
+cmp_exact
+content_check --regex "error .* during ln_normalize" $RSYSLOG_DYNNAME.othermsg
+
+exit_test
diff --git a/tests/pmnull-basic.sh b/tests/pmnull-basic.sh
new file mode 100755
index 0000000..3f3eda1
--- /dev/null
+++ b/tests/pmnull-basic.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# add 2016-12-07 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/pmnull/.libs/pmnull")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset")
+parser(name="custom.pmnull.withOrigin" type="pmnull")
+template(name="test" type="string" string="tag: %syslogtag%, pri: %pri%, syslogfacility: %syslogfacility%, syslogseverity: %syslogseverity% msg: %msg%\n")
+ruleset(name="ruleset" parser=["custom.pmnull.withOrigin", "rsyslog.pmnull"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="test")
+}
+'
+startup
+tcpflood -m1 -M "\"<189>16261: May 28 16:09:56.185: %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)\""
+shutdown_when_empty
+wait_shutdown
+echo 'tag: , pri: 13, syslogfacility: 1, syslogseverity: 5 msg: <189>16261: May 28 16:09:56.185: %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmnull-withparams.sh b/tests/pmnull-withparams.sh
new file mode 100755
index 0000000..95a48ee
--- /dev/null
+++ b/tests/pmnull-withparams.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# add 2016-12-08 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/pmnull/.libs/pmnull")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset")
+parser(name="custom.pmnull" type="pmnull" tag="mytag" syslogfacility="3" syslogseverity="1")
+template(name="test" type="string" string="tag: %syslogtag%, pri: %pri%, syslogfacility: %syslogfacility%, syslogseverity: %syslogseverity% msg: %msg%\n")
+ruleset(name="ruleset" parser=["custom.pmnull", "rsyslog.pmnull"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="test")
+}
+'
+startup
+tcpflood -m1 -M "\"<189>16261: May 28 16:09:56.185: %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)\""
+shutdown_when_empty
+wait_shutdown
+echo 'tag: mytag, pri: 25, syslogfacility: 3, syslogseverity: 1 msg: <189>16261: May 28 16:09:56.185: %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmrfc3164-AtSignsInHostname.sh b/tests/pmrfc3164-AtSignsInHostname.sh
new file mode 100755
index 0000000..d6a5a26
--- /dev/null
+++ b/tests/pmrfc3164-AtSignsInHostname.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="customparser")
+parser(name="custom.rfc3164" type="pmrfc3164" permit.AtSignsInHostname="on")
+template(name="outfmt" type="string" string="-%hostname%-\n")
+
+ruleset(name="customparser" parser="custom.rfc3164") {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname1 tag: msgnum:1\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostn@me2 tag: msgnum:2\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname3 tag:msgnum:3\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hos@name4 tag4:\""
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='-Hostname1-
+-Hostn@me2-
+-Hostname3-
+-Hos@name4-'
+cmp_exact
+
+exit_test
diff --git a/tests/pmrfc3164-AtSignsInHostname_off.sh b/tests/pmrfc3164-AtSignsInHostname_off.sh
new file mode 100755
index 0000000..1e1ac6c
--- /dev/null
+++ b/tests/pmrfc3164-AtSignsInHostname_off.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="customparser")
+parser(name="custom.rfc3164" type="pmrfc3164" permit.AtSignsInHostname="off")
+template(name="outfmt" type="string" string="-%hostname%-%syslogtag%-%msg%-\n")
+
+ruleset(name="customparser" parser="custom.rfc3164") {
+ :syslogtag, contains, "tag" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname1 tag: msgnum:1\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostn@me2 tag: msgnum:2\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname3 tag:msgnum:3\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hos@name4 tag4:\""
+shutdown_when_empty
+wait_shutdown
+echo '-Hostname1-tag:- msgnum:1-
+-Hostname3-tag:-msgnum:3-' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmrfc3164-defaultTag.sh b/tests/pmrfc3164-defaultTag.sh
new file mode 100755
index 0000000..f7a920b
--- /dev/null
+++ b/tests/pmrfc3164-defaultTag.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="customparser")
+parser(name="custom.rfc3164" type="pmrfc3164" permit.AtSignsInHostname="off"
+ force.tagEndingByColon="on")
+template(name="outfmt" type="string" string="?%hostname%?%syslogtag%?%msg%?\n")
+
+ruleset(name="customparser" parser="custom.rfc3164") {
+ :hostname, contains, "Hostname" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname1 msgnum:1\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname2 msgnum:2\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname3 tag msgnum:3\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname4 tag: msg\""
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='?Hostname1?-? msgnum:1?
+?Hostname2?-? msgnum:2?
+?Hostname3?-? tag msgnum:3?
+?Hostname4?tag:? msg?'
+cmp_exact
+
+exit_test
diff --git a/tests/pmrfc3164-json.sh b/tests/pmrfc3164-json.sh
new file mode 100755
index 0000000..6142383
--- /dev/null
+++ b/tests/pmrfc3164-json.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2017-12-12 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="rs")
+template(name="outfmt" type="string" string="%msg%---%rawmsg%\n")
+
+ruleset(name="rs") {
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+tcpflood -m1 -M "\"{ \\\"c1\\\":1 }\""
+tcpflood -m1 -M "\" { \\\"c2\\\":2 }\""
+tcpflood -m1 -M "\" [{ \\\"c3\\\":3 }]\""
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='{ "c1":1 }---{ "c1":1 }
+ { "c2":2 }--- { "c2":2 }
+ [{ "c3":3 }]--- [{ "c3":3 }]'
+echo "$EXPECTED" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ printf 'expected was\n'
+ echo "$EXPECTED"
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmrfc3164-msgFirstSpace.sh b/tests/pmrfc3164-msgFirstSpace.sh
new file mode 100755
index 0000000..e9f8679
--- /dev/null
+++ b/tests/pmrfc3164-msgFirstSpace.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="customparser")
+parser(name="custom.rfc3164" type="pmrfc3164" remove.msgFirstSpace="on")
+template(name="outfmt" type="string" string="-%msg%-\n")
+
+ruleset(name="customparser" parser="custom.rfc3164") {
+ :syslogtag, contains, "tag" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:2\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag:msgnum:3\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag4:\""
+shutdown_when_empty
+wait_shutdown
+echo '-msgnum:1-
+- msgnum:2-
+-msgnum:3-
+--' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmrfc3164-tagEndingByColon.sh b/tests/pmrfc3164-tagEndingByColon.sh
new file mode 100755
index 0000000..eb53048
--- /dev/null
+++ b/tests/pmrfc3164-tagEndingByColon.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2016-11-22 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="customparser")
+parser(name="custom.rfc3164" type="pmrfc3164" force.tagEndingByColon="on")
+template(name="outfmt" type="string" string="-%syslogtag%-%msg%-\n")
+
+ruleset(name="customparser" parser="custom.rfc3164") {
+ :syslogtag, contains, "tag" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname1 tag1: msgnum:1\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname2 tag2: msgnum:2\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname3 tag3 msgnum:3\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname4 tag4 :\""
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname5 tag5:msgnum:5\""
+shutdown_when_empty
+wait_shutdown
+echo '-tag1:- msgnum:1-
+-tag2:- msgnum:2-
+-tag5:-msgnum:5-' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmsnare-ccbackslash-udp.sh b/tests/pmsnare-ccbackslash-udp.sh
new file mode 100755
index 0000000..9d738fc
--- /dev/null
+++ b/tests/pmsnare-ccbackslash-udp.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/pmsnare/.libs/pmsnare")
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+global(localHostname="localhost"
+ parser.escapeControlCharactersCStyle="on")
+
+$EscapeControlCharactersOnReceive on
+
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -T "udp" -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};
+14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................
+14,user,info,MSWinEventLog,MSWinEventLog, 1\tSecurity\t00000000\tSun May 21 12:00:01.123\t4624\tMicrosoft-Windows-Security-Auditing\tN/A\tN/A\tSuccess Audit\thostname.domain\tLogon\t\tAn account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................'
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/pmsnare-ccbackslash.sh b/tests/pmsnare-ccbackslash.sh
new file mode 100755
index 0000000..60da84d
--- /dev/null
+++ b/tests/pmsnare-ccbackslash.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+setvar_RS_HOSTNAME
+generate_conf
+add_conf '
+module(load="../contrib/pmsnare/.libs/pmsnare")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+global(localHostname="localhost"
+ parser.escapeControlCharactersCStyle="on")
+
+$EscapeControlCharactersOnReceive on
+
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};
+14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................
+14,user,info,MSWinEventLog,MSWinEventLog, 1\tSecurity\t00000000\tSun May 21 12:00:01.123\t4624\tMicrosoft-Windows-Security-Auditing\tN/A\tN/A\tSuccess Audit\thostname.domain\tLogon\t\tAn account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................'
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/pmsnare-cccstyle-udp.sh b/tests/pmsnare-cccstyle-udp.sh
new file mode 100755
index 0000000..a8b44c9
--- /dev/null
+++ b/tests/pmsnare-cccstyle-udp.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+setvar_RS_HOSTNAME
+generate_conf
+add_conf '
+module(load="../contrib/pmsnare/.libs/pmsnare")
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+global(parser.escapeControlCharactersCStyle="on")
+
+$EscapeControlCharactersOnReceive on
+
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -T "udp" -M "\"<14>123456789: HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 2017 00:00:00: %ASA-4-102030: Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group "local_in" [0x0, 0x0]\""
+tcpflood -m1 -T "udp" -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,123456789,123456789:, HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................
+14,user,info,%ASA-4-102030,%ASA-4-102030:, Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group local_in [0x0, 0x0]
+14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};
+14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................
+14,user,info,MSWinEventLog,MSWinEventLog, 1\tSecurity\t00000000\tSun May 21 12:00:01.123\t4624\tMicrosoft-Windows-Security-Auditing\tN/A\tN/A\tSuccess Audit\thostname.domain\tLogon\t\tAn account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................'
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/pmsnare-cccstyle.sh b/tests/pmsnare-cccstyle.sh
new file mode 100755
index 0000000..6650642
--- /dev/null
+++ b/tests/pmsnare-cccstyle.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+setvar_RS_HOSTNAME
+generate_conf
+add_conf '
+module(load="../contrib/pmsnare/.libs/pmsnare")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+$EscapeControlCharactersOnReceive on
+global(
+ parser.escapeControlCharactersCStyle="on"
+)
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -M "\"<14>123456789: HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................\""
+tcpflood -m1 -M "\"<14>May 21 2017 00:00:00: %ASA-4-102030: Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group "local_in" [0x0, 0x0]\""
+tcpflood -m1 -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,123456789,123456789:, HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................
+14,user,info,%ASA-4-102030,%ASA-4-102030:, Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group local_in [0x0, 0x0]
+14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};
+14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................
+14,user,info,MSWinEventLog,MSWinEventLog, 1\tSecurity\t00000000\tSun May 21 12:00:01.123\t4624\tMicrosoft-Windows-Security-Auditing\tN/A\tN/A\tSuccess Audit\thostname.domain
+14,user,info,MSWinEventLog,MSWinEventLog, 1\tSecurity\t00000000\tSun May 21 12:00:01.123\t4624\tMicrosoft-Windows-Security-Auditing\tN/A\tN/A\tSuccess Audit\thostname.domain\tLogon\t\tAn account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................'
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/pmsnare-ccdefault-udp.sh b/tests/pmsnare-ccdefault-udp.sh
new file mode 100755
index 0000000..61787d0
--- /dev/null
+++ b/tests/pmsnare-ccdefault-udp.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/pmsnare/.libs/pmsnare")
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+global(localHostname="localhost")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -T "udp" -M "\"<14>123456789: HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 2017 00:00:00: %ASA-4-102030: Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group \\\"local_in\\\" [0x0, 0x0]\""
+tcpflood -m1 -T "udp" -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\""
+shutdown_when_empty
+wait_shutdown
+
+echo '14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,123456789,123456789:, HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................
+14,user,info,%ASA-4-102030,%ASA-4-102030:, Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group "local_in" [0x0, 0x0]
+14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};
+14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................
+14,user,info,MSWinEventLog,MSWinEventLog, 1#011Security#01100000000#011Sun May 21 12:00:01.123#0114624#011Microsoft-Windows-Security-Auditing#011N/A#011N/A#011Success Audit#011hostname.domain#011Logon#011#011An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmsnare-ccdefault.sh b/tests/pmsnare-ccdefault.sh
new file mode 100755
index 0000000..7a7a8dd
--- /dev/null
+++ b/tests/pmsnare-ccdefault.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/pmsnare/.libs/pmsnare")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+global(localHostname="localhost")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -M "\"<14>123456789: HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................\""
+tcpflood -m1 -M "\"<14>May 21 2017 00:00:00: %ASA-4-102030: Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group \\\"local_in\\\" [0x0, 0x0]\""
+tcpflood -m1 -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\""
+shutdown_when_empty
+wait_shutdown
+
+echo '14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,123456789,123456789:, HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................
+14,user,info,%ASA-4-102030,%ASA-4-102030:, Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group "local_in" [0x0, 0x0]
+14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};
+14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................
+14,user,info,MSWinEventLog,MSWinEventLog, 1#011Security#01100000000#011Sun May 21 12:00:01.123#0114624#011Microsoft-Windows-Security-Auditing#011N/A#011N/A#011Success Audit#011hostname.domain#011Logon#011#011An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmsnare-ccoff-udp.sh b/tests/pmsnare-ccoff-udp.sh
new file mode 100755
index 0000000..5c69451
--- /dev/null
+++ b/tests/pmsnare-ccoff-udp.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/pmsnare/.libs/pmsnare")
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+global(localHostname="localhost")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\""
+tcpflood -m1 -T "udp" -M "\"hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 5061 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain System Integrity Cryptographic operation. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Cryptographic Parameters: Provider Name: Microsoft Software Key Storage Provider Algorithm Name: RSA Key Name: le-c6bdb786-1851-4159-b5ea-5e3966571698 Key Type: Machine key. Cryptographic Operation: Operation: Open Key. Return Code: 0x0 -0000000000\""
+shutdown_when_empty
+wait_shutdown
+
+echo '14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,MSWinEventLog,MSWinEventLog, 1#011Security#01100000000#011Sun May 21 12:00:01.123#0114624#011Microsoft-Windows-Security-Auditing#011N/A#011N/A#011Success Audit#011hostname.domain#011Logon#011#011An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................
+13,user,notice,MSWinEventLog,MSWinEventLog, 1#011Security#01100000000#011Sun May 21 12:00:01.123#0115061#011Microsoft-Windows-Security-Auditing#011N/A#011N/A#011Success Audit#011hostname.domain#011System Integrity#011#011Cryptographic operation. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Cryptographic Parameters: Provider Name: Microsoft Software Key Storage Provider Algorithm Name: RSA Key Name: le-c6bdb786-1851-4159-b5ea-5e3966571698 Key Type: Machine key. Cryptographic Operation: Operation: Open Key. Return Code: 0x0#011-0000000000' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmsnare-ccoff.sh b/tests/pmsnare-ccoff.sh
new file mode 100755
index 0000000..33fffa6
--- /dev/null
+++ b/tests/pmsnare-ccoff.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/pmsnare/.libs/pmsnare")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+global(localHostname="localhost")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\""
+tcpflood -m1 -M "\"hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 5061 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain System Integrity Cryptographic operation. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Cryptographic Parameters: Provider Name: Microsoft Software Key Storage Provider Algorithm Name: RSA Key Name: le-c6bdb786-1851-4159-b5ea-5e3966571698 Key Type: Machine key. Cryptographic Operation: Operation: Open Key. Return Code: 0x0 -0000000000\""
+shutdown_when_empty
+wait_shutdown
+
+echo '14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,MSWinEventLog,MSWinEventLog, 1#011Security#01100000000#011Sun May 21 12:00:01.123#0114624#011Microsoft-Windows-Security-Auditing#011N/A#011N/A#011Success Audit#011hostname.domain#011Logon#011#011An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................
+13,user,notice,MSWinEventLog,MSWinEventLog, 1#011Security#01100000000#011Sun May 21 12:00:01.123#0115061#011Microsoft-Windows-Security-Auditing#011N/A#011N/A#011Success Audit#011hostname.domain#011System Integrity#011#011Cryptographic operation. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Cryptographic Parameters: Provider Name: Microsoft Software Key Storage Provider Algorithm Name: RSA Key Name: le-c6bdb786-1851-4159-b5ea-5e3966571698 Key Type: Machine key. Cryptographic Operation: Operation: Open Key. Return Code: 0x0#011-0000000000' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmsnare-default-udp.sh b/tests/pmsnare-default-udp.sh
new file mode 100755
index 0000000..25c8fde
--- /dev/null
+++ b/tests/pmsnare-default-udp.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+global(localHostname="localhost")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -T "udp" -M "\"<14>123456789: HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 2017 00:00:00: %ASA-4-102030: Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group \\\"local_in\\\" [0x0, 0x0]\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 2017 00:00:00: %ASA-6-102030: SFR requested ASA to bypass further packet redirection and process TCP flow from vlan_1233:192.168.0.11/10469 to vlan_12323:192.168.0.11/443 locally\""
+tcpflood -m1 -T "udp" -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\""
+tcpflood -m1 -T "udp" -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Rhttpproxy: verbose rhttpproxy[479C1B70] [Originator@6876 sub=Proxy Req 69725] Resolved endpoint : [N7Vmacore4Http16LocalServiceSpecE:0x00000000] _serverNamespace = /vpxa _isRedirect = false _port = 0000000000\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname MSWinEventLog 1 N/A 113977 Sun May 21 12:00:01.123 N/A nxlog N/A N/A N/A hostname N/A reconnecting to agent manager in 200 seconds N/A\""
+shutdown_when_empty
+wait_shutdown
+
+echo '14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,123456789,123456789:, HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................
+14,user,info,%ASA-4-102030,%ASA-4-102030:, Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group "local_in" [0x0, 0x0]
+14,user,info,%ASA-6-102030,%ASA-6-102030:, SFR requested ASA to bypass further packet redirection and process TCP flow from vlan_1233:192.168.0.11/10469 to vlan_12323:192.168.0.11/443 locally
+14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};
+14,user,info,Rhttpproxy,Rhttpproxy:, verbose rhttpproxy[479C1B70] [Originator@6876 sub=Proxy Req 69725] Resolved endpoint : [N7Vmacore4Http16LocalServiceSpecE:0x00000000] _serverNamespace = /vpxa _isRedirect = false _port = 0000000000
+14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................
+14,user,info,MSWinEventLog#0111#011N,MSWinEventLog#0111#011N/A#011113977#011Sun, May 21 12:00:01.123#011N/A#011nxlog#011N/A#011N/A#011N/A#011hostname#011N/A#011#011reconnecting to agent manager in 200 seconds#011N/A' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmsnare-default.sh b/tests/pmsnare-default.sh
new file mode 100755
index 0000000..bc80a6b
--- /dev/null
+++ b/tests/pmsnare-default.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+global(localHostname="localhost")
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -M "\"<14>123456789: HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................\""
+tcpflood -m1 -M "\"<14>May 21 2017 00:00:00: %ASA-4-102030: Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group \\\"local_in\\\" [0x0, 0x0]\""
+tcpflood -m1 -M "\"<14>May 21 2017 00:00:00: %ASA-6-102030: SFR requested ASA to bypass further packet redirection and process TCP flow from vlan_1233:192.168.0.11/10469 to vlan_12323:192.168.0.11/443 locally\""
+tcpflood -m1 -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\""
+tcpflood -m1 -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Rhttpproxy: verbose rhttpproxy[479C1B70] [Originator@6876 sub=Proxy Req 69725] Resolved endpoint : [N7Vmacore4Http16LocalServiceSpecE:0x00000000] _serverNamespace = /vpxa _isRedirect = false _port = 0000000000\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname MSWinEventLog 1 N/A 113977 Sun May 21 12:00:01.123 N/A nxlog N/A N/A N/A hostname N/A reconnecting to agent manager in 200 seconds N/A\""
+shutdown_when_empty
+wait_shutdown
+
+echo '14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,123456789,123456789:, HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................
+14,user,info,%ASA-4-102030,%ASA-4-102030:, Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group "local_in" [0x0, 0x0]
+14,user,info,%ASA-6-102030,%ASA-6-102030:, SFR requested ASA to bypass further packet redirection and process TCP flow from vlan_1233:192.168.0.11/10469 to vlan_12323:192.168.0.11/443 locally
+14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};
+14,user,info,Rhttpproxy,Rhttpproxy:, verbose rhttpproxy[479C1B70] [Originator@6876 sub=Proxy Req 69725] Resolved endpoint : [N7Vmacore4Http16LocalServiceSpecE:0x00000000] _serverNamespace = /vpxa _isRedirect = false _port = 0000000000
+14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................
+14,user,info,MSWinEventLog#0111#011N,MSWinEventLog#0111#011N/A#011113977#011Sun, May 21 12:00:01.123#011N/A#011nxlog#011N/A#011N/A#011N/A#011hostname#011N/A#011#011reconnecting to agent manager in 200 seconds#011N/A' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/pmsnare-modoverride-udp.sh b/tests/pmsnare-modoverride-udp.sh
new file mode 100755
index 0000000..ad45382
--- /dev/null
+++ b/tests/pmsnare-modoverride-udp.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/pmsnare/.libs/pmsnare")
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+global(
+ parser.escapeControlCharactersOnReceive="off"
+ parser.escapeControlCharacterTab="off"
+ parser.escapeControlCharactersCStyle="on"
+ parser.controlCharacterEscapePrefix="#"
+)
+
+parser(
+ name="modoverride.snare"
+ type="pmsnare"
+ parser.escapeControlCharactersOnReceive="on"
+ parser.escapeControlCharacterTab="on"
+ parser.escapeControlCharactersCStyle="off"
+ parser.controlCharacterEscapePrefix="\\"
+)
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1" parser=["modoverride.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -T "udp" -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\""
+tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog\\\\0111\\\\011Security\\\\01100000000\\\\011Sun May 21 12:00:01.123\\\\0114624\\\\011Microsoft-Windows-Security-Auditing\\\\011N/A\\\\011N/A\\\\011Success Audit\\\\011hostname.domain\\\\011Logon\\\\011\\\\011An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};
+14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................
+14,user,info,MSWinEventLog,MSWinEventLog, 1\011Security\01100000000\011Sun May 21 12:00:01.123\0114624\011Microsoft-Windows-Security-Auditing\011N/A\011N/A\011Success Audit\011hostname.domain\011Logon\011\011An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................'
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/pmsnare-modoverride.sh b/tests/pmsnare-modoverride.sh
new file mode 100755
index 0000000..1faf484
--- /dev/null
+++ b/tests/pmsnare-modoverride.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../contrib/pmsnare/.libs/pmsnare")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+global(
+ parser.escapeControlCharactersOnReceive="off"
+ parser.escapeControlCharacterTab="off"
+ parser.escapeControlCharactersCStyle="on"
+ parser.controlCharacterEscapePrefix="#"
+)
+
+parser(
+ name="modoverride.snare"
+ type="pmsnare"
+ parser.escapeControlCharactersOnReceive="on"
+ parser.escapeControlCharacterTab="on"
+ parser.escapeControlCharactersCStyle="off"
+ parser.controlCharacterEscapePrefix="\\"
+)
+
+template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n")
+
+ruleset(name="ruleset1" parser=["modoverride.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\""
+tcpflood -m1 -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\""
+tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog\\\\0111\\\\011Security\\\\01100000000\\\\011Sun May 21 12:00:01.123\\\\0114624\\\\011Microsoft-Windows-Security-Auditing\\\\011N/A\\\\011N/A\\\\011Success Audit\\\\011hostname.domain\\\\011Logon\\\\011\\\\011An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti
+14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};
+14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................
+14,user,info,MSWinEventLog,MSWinEventLog, 1\011Security\01100000000\011Sun May 21 12:00:01.123\0114624\011Microsoft-Windows-Security-Auditing\011N/A\011N/A\011Success Audit\011hostname.domain\011Logon\011\011An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................'
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/privdrop_common.sh b/tests/privdrop_common.sh
new file mode 100755
index 0000000..dabc088
--- /dev/null
+++ b/tests/privdrop_common.sh
@@ -0,0 +1,110 @@
+#!/bin/bash
+# added 2016-04-15 by Thomas D., released under ASL 2.0
+# Several tests need another user/group to test impersonation.
+# This script can be sourced to prevent duplicated code.
+
+# To support <bash-4.2 which don't support "declare -g" we declare
+# the array outside of the function
+declare -A TESTBENCH_TESTUSER
+
+rsyslog_testbench_setup_testuser() {
+ local has_testuser=
+ local testusername=
+ local testgroupname=
+
+ if [ -z "${EUID}" ]; then
+ # Should never happen
+ echo "FATAL ERROR: \$EUID not set!"
+ exit 1
+ fi
+
+ if [ ${EUID} -eq 0 ]; then
+ # Only root is able to become a different user
+
+ local testusers=("rsyslog" "syslog" "daemon")
+
+ if [ -n "${RSYSLOG_TESTUSER}" ]; then
+ # User has specified an username/uid we should use in testbench
+ testusers=("${RSYSLOG_TESTUSER}" ${testusers[@]})
+ fi
+
+ local testuser=
+ for testuser in "${testusers[@]}"; do
+ testusername=$(id --user --name ${testuser} 2>/dev/null)
+ if [ -z "${testusername}" ]; then
+ echo "'id' did not find user \"${testuser}\" ... skipping, trying next user!"
+ continue
+ fi
+
+ testgroupname=$(id --group --name ${testuser} 2>/dev/null)
+ if [ -z "${testgroupname}" ]; then
+ echo "'id' did not find a primary group for \"${testuser}\" ... skipping, trying next user!"
+ continue
+ fi
+
+ has_testuser="${testuser}"
+ break
+ done
+ if [ -z "${has_testuser}" ]; then
+ echo "ERROR: running as root and no suiteable testuser found - skipping test"
+ echo 'You mas set a testuser via the RSYSLOG_TESTUSER environment variable'
+ exit 77
+ fi
+ echo "WARNING: making work directory world-writable, as we need this to be able to"
+ echo " open and process files after privilege drop. This is NOT automatically"
+ echo " undone."
+ chmod a+w .
+ fi
+
+ if [ -z "${has_testuser}" ]; then
+ testgroupname=$(id --group --name ${EUID} 2>/dev/null)
+ if [ -z "${testgroupname}" ]; then
+ echo "Skipping ... please set RSYSLOG_TESTUSER or make sure the user running the testbench has a primary group!"
+ exit_test
+ exit 0
+ else
+ has_testuser="${EUID}"
+ fi
+ fi
+
+ _rsyslog_testbench_declare_testuser ${has_testuser}
+}
+
+_rsyslog_testbench_declare_testuser() {
+ local testuser=$1
+
+ local testusername=$(id --user --name ${testuser} 2>/dev/null)
+ if [ -z "${testusername}" ]; then
+ # Should never happen
+ echo "FATAL ERROR: Could not get username for user \"${testuser}\"!"
+ exit 1
+ fi
+
+ local testuid=$(id --user ${testuser} 2>/dev/null)
+ if [ -z "${testuid}" ]; then
+ # Should never happen
+ echo "FATAL ERROR: Could not get uid for user \"${testuser}\"!"
+ exit 1
+ fi
+
+ local testgroupname=$(id --group --name ${testuser} 2>/dev/null)
+ if [ -z "${testgroupname}" ]; then
+ # Should never happen
+ echo "FATAL ERROR: Could not get uid of user \"${testuser}\"!"
+ exit 1
+ fi
+
+ local testgid=$(id --group ${testuser} 2>/dev/null)
+ if [ -z "${testgid}" ]; then
+ # Should never happen
+ echo "FATAL ERROR: Could not get primary gid of user \"${testuser}\"!"
+ exit 1
+ fi
+
+ echo "Will use user \"${testusername}\" (#${testuid}) and group \"${testgroupname}\" (#${testgid})"
+
+ TESTBENCH_TESTUSER[username]=${testusername}
+ TESTBENCH_TESTUSER[uid]=${testuid}
+ TESTBENCH_TESTUSER[groupname]=${testgroupname}
+ TESTBENCH_TESTUSER[gid]=${testgid}
+}
diff --git a/tests/privdropabortonidfail.sh b/tests/privdropabortonidfail.sh
new file mode 100755
index 0000000..842158a
--- /dev/null
+++ b/tests/privdropabortonidfail.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# add 2021-10-12 by alorbach, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog"
+
+skip_platform "SunOS" "This test currently does not work on Solaris."
+export TESTBENCH_TESTUSER1="USER_${RSYSLOG_DYNNAME}_1"
+export TESTBENCH_TESTUSER2="USER_${RSYSLOG_DYNNAME}_2"
+
+generate_conf
+add_conf '
+global(
+ security.abortOnIDResolutionFail="off"
+)
+
+template(name="outfmt" type="list") {
+ property(name="msg" compressSpace="on")
+ constant(value="\n")
+}
+action( type="omfile"
+ template="outfmt"
+ file="'${RSYSLOG_OUT_LOG}'"
+)
+
+action( type="omfile"
+ template="outfmt"
+ file="'${RSYSLOG_DYNNAME}'.dummy.log"
+ FileOwner="'${TESTBENCH_TESTUSER1}'"
+ FileGroup="'${TESTBENCH_TESTUSER1}'"
+ DirOwner="'${TESTBENCH_TESTUSER2}'"
+ DirGroup="'${TESTBENCH_TESTUSER2}'"
+ )
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "ID for user '${TESTBENCH_TESTUSER1}' could not be found"
+content_check --regex "ID for user '${TESTBENCH_TESTUSER2}' could not be found"
+exit_test
diff --git a/tests/privdropabortonidfaillegacy.sh b/tests/privdropabortonidfaillegacy.sh
new file mode 100755
index 0000000..bc4b8a1
--- /dev/null
+++ b/tests/privdropabortonidfaillegacy.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# add 2021-10-12 by alorbach, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog"
+
+skip_platform "SunOS" "This test currently does not work on Solaris."
+export TESTBENCH_TESTUSER1="USER_${RSYSLOG_DYNNAME}_1"
+export TESTBENCH_TESTUSER2="USER_${RSYSLOG_DYNNAME}_2"
+
+generate_conf
+add_conf '
+global(
+ security.abortOnIDResolutionFail="off"
+)
+
+template(name="outfmt" type="list") {
+ property(name="msg" compressSpace="on")
+ constant(value="\n")
+}
+
+$FileOwner '${TESTBENCH_TESTUSER1}'
+$FileGroup '${TESTBENCH_TESTUSER1}'
+$DirOwner '${TESTBENCH_TESTUSER2}'
+$DirGroup '${TESTBENCH_TESTUSER2}'
+
+action( type="omfile"
+ template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "ID for user '${TESTBENCH_TESTUSER1}' could not be found"
+content_check --regex "ID for user '${TESTBENCH_TESTUSER2}' could not be found"
+
+exit_test
diff --git a/tests/privdropgroup.sh b/tests/privdropgroup.sh
new file mode 100755
index 0000000..276539b
--- /dev/null
+++ b/tests/privdropgroup.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# addd 2016-03-24 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on Solaris."
+. $srcdir/privdrop_common.sh
+rsyslog_testbench_setup_testuser
+
+generate_conf
+add_conf '
+global(privdrop.group.keepsupplemental="on")
+template(name="outfmt" type="list") {
+ property(name="msg" compressSpace="on")
+ constant(value="\n")
+}
+action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+$PrivDropToGroup '${TESTBENCH_TESTUSER[groupname]}'
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "groupid.*${TESTBENCH_TESTUSER[gid]}"
+if [ ! $? -eq 0 ]; then
+ echo "message indicating drop to group \"${TESTBENCH_TESTUSER[groupname]}\" (#${TESTBENCH_TESTUSER[gid]}) is missing:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/privdropgroupid.sh b/tests/privdropgroupid.sh
new file mode 100755
index 0000000..dfbbba4
--- /dev/null
+++ b/tests/privdropgroupid.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# addd 2016-03-24 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/privdrop_common.sh
+rsyslog_testbench_setup_testuser
+
+generate_conf
+add_conf '
+global(privdrop.group.keepsupplemental="on")
+template(name="outfmt" type="list") {
+ property(name="msg" compressSpace="on")
+ constant(value="\n")
+}
+action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+$PrivDropToGroupID '${TESTBENCH_TESTUSER[gid]}'
+'
+#add_conf "\$PrivDropToGroupID ${TESTBENCH_TESTUSER[gid]}"
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "groupid.*${TESTBENCH_TESTUSER[gid]}"
+exit_test
diff --git a/tests/privdropuser.sh b/tests/privdropuser.sh
new file mode 100755
index 0000000..acbf450
--- /dev/null
+++ b/tests/privdropuser.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# addd 2016-03-24 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on Solaris."
+. $srcdir/privdrop_common.sh
+rsyslog_testbench_setup_testuser
+
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="msg" compressSpace="on")
+ constant(value="\n")
+}
+action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+$PrivDropToUser '${TESTBENCH_TESTUSER[username]}'
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "userid.*${TESTBENCH_TESTUSER[uid]}"
+exit_test
diff --git a/tests/privdropuserid.sh b/tests/privdropuserid.sh
new file mode 100755
index 0000000..bc2fdf9
--- /dev/null
+++ b/tests/privdropuserid.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# addd 2016-03-24 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on Solaris."
+. $srcdir/privdrop_common.sh
+rsyslog_testbench_setup_testuser
+
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="msg" compressSpace="on")
+ constant(value="\n")
+}
+action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+$PrivDropToUserID '${TESTBENCH_TESTUSER[uid]}'
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "userid.*${TESTBENCH_TESTUSER[uid]}"
+exit_test
diff --git a/tests/prop-all-json-concurrency.sh b/tests/prop-all-json-concurrency.sh
new file mode 100755
index 0000000..4f7b271
--- /dev/null
+++ b/tests/prop-all-json-concurrency.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Test concurrency of exec_template function with msg variables
+# Added 2015-12-16 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[prop-all-json-concurrency.sh\]: testing concurrency of $!all-json variables
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="interim" type="string" string="%$!tree!here!nbr%")
+template(name="outfmt" type="string" string="%$.interim%\n")
+template(name="all-json" type="string" string="%$!%\n")
+
+if $msg contains "msgnum:" then {
+ set $!tree!here!nbr = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="all-json"
+ queue.type="linkedList")
+
+ set $.interim = $!all-json;
+ unset $!tree!here!nbr;
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt"
+ queue.type="fixedArray")
+}
+'
+startup
+sleep 1
+tcpflood -m500000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 499999
+exit_test
diff --git a/tests/prop-jsonmesg-vg.sh b/tests/prop-jsonmesg-vg.sh
new file mode 100755
index 0000000..3c3fada
--- /dev/null
+++ b/tests/prop-jsonmesg-vg.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# Added 2018-01-17 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="list"){
+ property(name="jsonmesg")
+ constant(value="\n")
+}
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+
+startup_vg
+tcpflood -m1 -y
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+export EXPECTED='"msg": "msgnum:00000000:", '
+. $srcdir/diag.sh grep-check
+exit_test
diff --git a/tests/prop-programname-with-slashes.sh b/tests/prop-programname-with-slashes.sh
new file mode 100755
index 0000000..67d9481
--- /dev/null
+++ b/tests/prop-programname-with-slashes.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# addd 2017-01142 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+global(parser.PermitSlashInProgramname="on")
+
+template(name="outfmt" type="string" string="%syslogtag%,%programname%\n")
+local0.* action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m 1 -M "\"<133>2011-03-01T11:22:12Z host tag/with/slashes msgh ...x\""
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "tag/with/slashes,tag/with/slashes" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid output generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/prop-programname.sh b/tests/prop-programname.sh
new file mode 100755
index 0000000..d717351
--- /dev/null
+++ b/tests/prop-programname.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# addd 2017-01142 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%syslogtag%,%programname%\n")
+local0.* action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m 1 -M "\"<133>2011-03-01T11:22:12Z host tag/with/slashes msgh ...x\""
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="tag/with/slashes,tag"
+cmp_exact $RSYSLOG_OUT_LOG
+exit_test
diff --git a/tests/proprepltest-nolimittag-udp.sh b/tests/proprepltest-nolimittag-udp.sh
new file mode 100755
index 0000000..38738d0
--- /dev/null
+++ b/tests/proprepltest-nolimittag-udp.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'")
+
+template(name="outfmt" type="string" string="+%syslogtag%+\n")
+
+:pri, contains, "167" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 0 Rest of message...\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901 Rest of message...\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901-toolong Rest of message...\""
+shutdown_when_empty
+wait_shutdown
+
+echo '+TAG:+
++0+
++01234567890123456789012345678901+
++01234567890123456789012345678901-toolong+' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/proprepltest-nolimittag.sh b/tests/proprepltest-nolimittag.sh
new file mode 100755
index 0000000..9f57525
--- /dev/null
+++ b/tests/proprepltest-nolimittag.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="+%syslogtag%+\n")
+
+:pri, contains, "167" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+
+
+'
+startup
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...\""
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 0 Rest of message...\""
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901 Rest of message...\""
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901-toolong Rest of message...\""
+shutdown_when_empty
+wait_shutdown
+
+echo '+TAG:+
++0+
++01234567890123456789012345678901+
++01234567890123456789012345678901-toolong+' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/proprepltest-rfctag-udp.sh b/tests/proprepltest-rfctag-udp.sh
new file mode 100755
index 0000000..501505a
--- /dev/null
+++ b/tests/proprepltest-rfctag-udp.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'")
+
+template(name="outfmt" type="string" string="+%syslogtag:1:32%+\n")
+
+:pri, contains, "167" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 0 Rest of message...\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901 Rest of message...\""
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901-toolong Rest of message...\""
+shutdown_when_empty
+wait_shutdown
+
+echo '+TAG:+
++0+
++01234567890123456789012345678901+
++01234567890123456789012345678901+' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/proprepltest-rfctag.sh b/tests/proprepltest-rfctag.sh
new file mode 100755
index 0000000..3d3fc16
--- /dev/null
+++ b/tests/proprepltest-rfctag.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="+%syslogtag:1:32%+\n")
+
+:pri, contains, "167" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+
+
+'
+startup
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...\""
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 0 Rest of message...\""
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901 Rest of message...\""
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901-toolong Rest of message...\""
+shutdown_when_empty
+wait_shutdown
+
+echo '+TAG:+
++0+
++01234567890123456789012345678901+
++01234567890123456789012345678901+' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/queue-direct-with-no-params.sh b/tests/queue-direct-with-no-params.sh
new file mode 100755
index 0000000..4e5c999
--- /dev/null
+++ b/tests/queue-direct-with-no-params.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# added 2019-11-14 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+check_not_present "queue is in direct mode, but parameters have been set"
+exit_test
diff --git a/tests/queue-direct-with-params-given.sh b/tests/queue-direct-with-params-given.sh
new file mode 100755
index 0000000..3593a91
--- /dev/null
+++ b/tests/queue-direct-with-params-given.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# added 2019-11-14 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" queue.mindequeuebatchsize="20")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check "queue is in direct mode, but parameters have been set"
+exit_test
diff --git a/tests/queue-encryption-da.sh b/tests/queue-encryption-da.sh
new file mode 100755
index 0000000..9d6e9b2
--- /dev/null
+++ b/tests/queue-encryption-da.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# addd 2018-09-28 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omtesting/.libs/omtesting")
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+main_queue(queue.filename="mainq"
+ queue.type="linkedList"
+ queue.maxDiskSpace="4m"
+ queue.maxfilesize="1m"
+ queue.timeoutenqueue="300000"
+ queue.lowwatermark="5000"
+
+ queue.cry.provider="gcry"
+ queue.cry.key="1234567890123456"
+ queue.saveonshutdown="on"
+)
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+
+:omtesting:sleep 0 5000
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+injectmsg 0 1000
+shutdown_immediate
+wait_shutdown
+echo INFO: queue files in ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+check_not_present "msgnum:0000" ${RSYSLOG_DYNNAME}.spool/mainq.0*
+exit_test
diff --git a/tests/queue-encryption-disk.sh b/tests/queue-encryption-disk.sh
new file mode 100755
index 0000000..9f7825c
--- /dev/null
+++ b/tests/queue-encryption-disk.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# addd 2018-09-28 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omtesting/.libs/omtesting")
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+main_queue(queue.filename="mainq"
+ queue.type="disk"
+ queue.maxDiskSpace="4m"
+ queue.maxfilesize="1m"
+ queue.timeoutenqueue="300000"
+ queue.lowwatermark="5000"
+
+ queue.cry.provider="gcry"
+ queue.cry.key="1234567890123456"
+ queue.saveonshutdown="on"
+)
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+
+:omtesting:sleep 0 5000
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+injectmsg 0 1000
+shutdown_immediate
+wait_shutdown
+echo INFO: queue files in ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+check_not_present "msgnum:0000" ${RSYSLOG_DYNNAME}.spool/mainq.0*
+exit_test
diff --git a/tests/queue-encryption-disk_keyfile-vg.sh b/tests/queue-encryption-disk_keyfile-vg.sh
new file mode 100755
index 0000000..df15c75
--- /dev/null
+++ b/tests/queue-encryption-disk_keyfile-vg.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# addd 2018-09-30 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omtesting/.libs/omtesting")
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+main_queue(queue.filename="mainq"
+ queue.type="disk"
+ queue.maxDiskSpace="4m"
+ queue.maxfilesize="1m"
+ queue.timeoutshutdown="20000"
+ queue.timeoutenqueue="300000"
+ queue.lowwatermark="5000"
+
+ queue.cry.provider="gcry"
+ queue.cry.keyfile="'$RSYSLOG_DYNNAME.keyfile'"
+ queue.saveonshutdown="on"
+)
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+
+:omtesting:sleep 0 5000
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+printf "1234567890123456" > $RSYSLOG_DYNNAME.keyfile
+startup_vg_noleak # we WILL leak due to the immediate shutdown
+injectmsg 0 1000
+shutdown_immediate
+wait_shutdown_vg
+check_exit_vg
+echo INFO: queue files in ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+check_not_present "msgnum:0000" ${RSYSLOG_DYNNAME}.spool/mainq.0*
+exit_test
diff --git a/tests/queue-encryption-disk_keyfile.sh b/tests/queue-encryption-disk_keyfile.sh
new file mode 100755
index 0000000..cc6274d
--- /dev/null
+++ b/tests/queue-encryption-disk_keyfile.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# addd 2018-09-30 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omtesting/.libs/omtesting")
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+main_queue(queue.filename="mainq"
+ queue.type="disk"
+ queue.maxDiskSpace="4m"
+ queue.maxfilesize="1m"
+ queue.timeoutenqueue="300000"
+ queue.lowwatermark="5000"
+
+ queue.cry.provider="gcry"
+ queue.cry.keyfile="'$RSYSLOG_DYNNAME.keyfile'"
+ queue.saveonshutdown="on"
+)
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+
+:omtesting:sleep 0 5000
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+printf "1234567890123456" > $RSYSLOG_DYNNAME.keyfile
+startup
+injectmsg 0 1000
+shutdown_immediate
+wait_shutdown
+echo INFO: queue files in ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+check_not_present "msgnum:0000" ${RSYSLOG_DYNNAME}.spool/mainq.0*
+exit_test
diff --git a/tests/queue-encryption-disk_keyprog.sh b/tests/queue-encryption-disk_keyprog.sh
new file mode 100755
index 0000000..0bf756b
--- /dev/null
+++ b/tests/queue-encryption-disk_keyprog.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# addd 2018-10-01 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/omtesting/.libs/omtesting")
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+main_queue(queue.filename="mainq"
+ queue.type="disk"
+ queue.maxDiskSpace="4m"
+ queue.maxfilesize="1m"
+ queue.timeoutenqueue="300000"
+ queue.lowwatermark="5000"
+
+ queue.cry.provider="gcry"
+ queue.cry.keyprogram="./'$RSYSLOG_DYNNAME.keyprogram'"
+ queue.saveonshutdown="on"
+)
+
+template(name="outfmt" type="string"
+ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+
+:omtesting:sleep 0 5000
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+echo '#!/bin/bash
+echo RSYSLOG-KEY-PROVIDER:0
+echo 16
+echo "1234567890123456"' >> $RSYSLOG_DYNNAME.keyprogram
+chmod +x $RSYSLOG_DYNNAME.keyprogram
+startup
+injectmsg 0 1000
+shutdown_immediate
+wait_shutdown
+echo INFO: queue files in ${RSYSLOG_DYNNAME}.spool:
+ls -l ${RSYSLOG_DYNNAME}.spool
+check_not_present "msgnum:0000" ${RSYSLOG_DYNNAME}.spool/mainq.0*
+exit_test
diff --git a/tests/queue-minbatch-queuefull.sh b/tests/queue-minbatch-queuefull.sh
new file mode 100755
index 0000000..afcf1a9
--- /dev/null
+++ b/tests/queue-minbatch-queuefull.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# added 2019-01-14 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on Solaris - see https://github.com/rsyslog/rsyslog/issues/3513"
+export NUMMESSAGES=10000
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ queue.type="linkedList"
+ queue.size="2001"
+ queue.dequeuebatchsize="2001"
+ queue.mindequeuebatchsize="2001"
+ queue.minDequeueBatchSize.timeout="2000"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/queue-minbatch.sh b/tests/queue-minbatch.sh
new file mode 100755
index 0000000..408b700
--- /dev/null
+++ b/tests/queue-minbatch.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# added 2019-01-10 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+skip_platform "SunOS" "This test currently does not work on Solaris - see https://github.com/rsyslog/rsyslog/issues/3513"
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ queue.type="linkedList"
+ queue.mindequeuebatchsize="20"
+ queue.minDequeueBatchSize.timeout="30000" # 30 sec
+ file="'$RSYSLOG_OUT_LOG'")
+'
+#
+# Note: this test is a bit tricky, as we depend on timeouts. That in turn
+# calls for trouble with slow test machines. As we really want to test the
+# timeout itself, we need to find a way around. What we do is use pretty
+# timeout values, which should also work on slow machines. Of course, that
+# also means the test is pretty slow, but that's just how it is...
+# Note that we may still (hopefully very) occasional failures on some
+# CI machines with very high-load.
+#
+startup
+injectmsg 0 10
+printf '%s waiting a bit to ensure batch is not yet written\n' "$(tb_timestamp)"
+sleep 5
+# at this point in time, nothing must have been written and so the output
+# file must not even exist.
+check_file_not_exists $RSYSLOG_OUT_NAME
+printf '%s %s\n' "$(tb_timestamp)" "output file does not yet exist - GOOD!"
+printf '%s waiting on timeout\n' "$(tb_timestamp)"
+sleep 30
+printf '%s done waiting on timeout\n' "$(tb_timestamp)"
+wait_seq_check 0 9
+seq_check 0 9
+
+printf '%s injecting new messages and waiting for shutdown\n' "$(tb_timestamp)"
+injectmsg 10 20
+shutdown_when_empty
+wait_shutdown
+seq_check 0 29
+exit_test
diff --git a/tests/queue-persist-drvr.sh b/tests/queue-persist-drvr.sh
new file mode 100755
index 0000000..7f666d1
--- /dev/null
+++ b/tests/queue-persist-drvr.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+# Test for queue data persisting at shutdown. The
+# plan is to start an instance, emit some data, do a relatively
+# fast shutdown and then re-start the engine to process the
+# remaining data.
+# added 2009-05-27 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+# uncomment for debugging support:
+echo testing memory queue persisting to disk, mode $1
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 1
+$MainMsgQueueSaveOnShutdown on
+$InputTCPServerRun '$TCPFLOOD_PORT'
+
+$ModLoad ../plugins/omtesting/.libs/omtesting
+
+# set spool locations and switch queue to disk-only mode
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+$MainMsgQueueFilename mainq
+$IncludeConfig '${RSYSLOG_DYNNAME}'work-queuemode.conf
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+
+$IncludeConfig '${RSYSLOG_DYNNAME}'work-delay.conf
+'
+# prepare config
+echo \$MainMsgQueueType $1 > ${RSYSLOG_DYNNAME}work-queuemode.conf
+echo "*.* :omtesting:sleep 0 1000" > ${RSYSLOG_DYNNAME}work-delay.conf
+
+# inject 5000 msgs, so that we do not hit the high watermark
+startup
+injectmsg 0 5000
+shutdown_immediate
+wait_shutdown
+check_mainq_spool
+
+# restart engine and have rest processed
+#remove delay
+echo "#" > ${RSYSLOG_DYNNAME}work-delay.conf
+startup
+shutdown_when_empty # shut down rsyslogd when done processing messages
+./msleep 1000
+wait_shutdown
+# note: we need to permit duplicate messages, as due to the forced
+# shutdown some messages may be flagged as "unprocessed" while they
+# actually were processed. This is inline with rsyslog's philosophy
+# to better duplicate than loose messages. Duplicate messages are
+# permitted by the -d seq-check option.
+seq_check 0 4999 -d
+exit_test
diff --git a/tests/queue-persist.sh b/tests/queue-persist.sh
new file mode 100755
index 0000000..519aa0b
--- /dev/null
+++ b/tests/queue-persist.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Test for queue data persisting at shutdown. We use the actual driver
+# to carry out multiple tests with different queue modes
+# added 2009-05-27 by Rgerhards
+# This file is part of the rsyslog project, released ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/queue-persist-drvr.sh LinkedList
+. $srcdir/queue-persist-drvr.sh FixedArray
+# the disk test should not fail, however, the config is extreme and using
+# it more or less is a config error
+. $srcdir/queue-persist-drvr.sh Disk
+# we do not test Direct mode because this absolute can not work in direct mode
+# (maybe we should do a fail-type of test?)
diff --git a/tests/queue_warnmsg-oversize.sh b/tests/queue_warnmsg-oversize.sh
new file mode 100755
index 0000000..b3803e8
--- /dev/null
+++ b/tests/queue_warnmsg-oversize.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# add 2019-04-18 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'"
+ queue.type="linkedList" queue.size="500001")
+'
+
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "warning.*queue.size=500001 is very large"
+
+exit_test
diff --git a/tests/random.sh b/tests/random.sh
new file mode 100755
index 0000000..b074142
--- /dev/null
+++ b/tests/random.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Test if rsyslog survives sending truly random data to it...
+#
+# added 2010-04-01 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+# The random data will generate TCP framing error messages. We will
+# not clutter the test output with them. So we disable error messages
+# to stderr.
+$ErrorMessagesToStderr off
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%rawmsg%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+*.* /dev/null
+'
+startup
+# generate random data
+./randomgen -f $RSYSLOG_DYNNAME.random.data -s 100000
+ls -l $RSYSLOG_DYNNAME.random.data
+tcpflood -B -I $RSYSLOG_DYNNAME.random.data -c5 -C10
+shutdown_when_empty # shut down rsyslogd when done processing messages
+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
+exit_test
diff --git a/tests/randomgen.c b/tests/randomgen.c
new file mode 100644
index 0000000..046ca1a
--- /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-2016 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 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/rawmsg-after-pri.sh b/tests/rawmsg-after-pri.sh
new file mode 100755
index 0000000..30470d4
--- /dev/null
+++ b/tests/rawmsg-after-pri.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(type="string" name="outfmt" string="%rawmsg-after-pri%\n")
+if $syslogfacility-text == "local0" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m1 -P 129
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # and wait for it to terminate
+NUMLINES=$(grep -c "^Mar 1 01:00:00 172.20.245.8 tag msgnum:00000000:$" $RSYSLOG_OUT_LOG 2>/dev/null)
+
+if [ -z $NUMLINES ]; then
+ echo "ERROR: output file seems not to exist"
+ ls -l $RSYSLOG_OUT_LOG
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+else
+ if [ ! $NUMLINES -eq 1 ]; then
+ echo "ERROR: output format does not match expectation"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+ fi
+fi
+exit_test
diff --git a/tests/rcvr_fail_restore.sh b/tests/rcvr_fail_restore.sh
new file mode 100755
index 0000000..53dd891
--- /dev/null
+++ b/tests/rcvr_fail_restore.sh
@@ -0,0 +1,168 @@
+#!/bin/bash
+# Copyright (C) 2011 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test does not work on FreeBSD - problems with os utility option switches"
+#
+# STEP1: start both instances and send 1000 messages.
+# Note: receiver is instance 1, sender instance 2.
+#
+# start up the instances. Note that the environment settings can be changed to
+# set instance-specific debugging parameters!
+#export RSYSLOG_DEBUG="debug nostdout"
+#export RSYSLOG_DEBUGLOG="log2"
+echo starting receiver
+generate_conf
+add_conf '
+# then SENDER sends to this port (not tcpflood!)
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" ./'$RSYSLOG_OUT_LOG';outfmt
+'
+startup
+export PORT_RCVR="$TCPFLOOD_PORT"
+#export RSYSLOG_DEBUG="debug nostdout"
+#export RSYSLOG_DEBUGLOG="log"
+#valgrind="valgrind"
+echo starting sender
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)"
+add_conf '
+$WorkDirectory '$RSYSLOG_DYNNAME'.spool
+$MainMsgQueueSize 2000
+$MainMsgQueueLowWaterMark 800
+$MainMsgQueueHighWaterMark 1000
+$MainMsgQueueDequeueBatchSize 1
+$MainMsgQueueMaxFileSize 1g
+$MainMsgQueueWorkerThreads 1
+$MainMsgQueueFileName mainq
+
+# we use the shortest resume interval a) to let the test not run too long
+# and b) make sure some retries happen before the reconnect
+$ActionResumeInterval 1
+$ActionSendResendLastMsgOnReconnect on
+$ActionResumeRetryCount -1
+*.* @@127.0.0.1:'$PORT_RCVR'
+' 2
+startup 2
+# re-set params so that new instances do not thrash it...
+#unset RSYSLOG_DEBUG
+#unset RSYSLOG_DEBUGLOG
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 1 1000
+wait_queueempty
+./msleep 1000 # let things settle down a bit
+
+#
+# Step 2: shutdown receiver, then send some more data, which then
+# needs to go into the queue.
+#
+echo step 2
+
+shutdown_when_empty
+wait_shutdown
+
+injectmsg2 1001 10000
+./msleep 3000 # make sure some retries happen (retry interval is set to 3 second)
+get_mainqueuesize 2
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+#
+# Step 3: restart receiver, wait that the sender drains its queue
+$InputTCPServerRun '$PORT_RCVR'
+#
+echo step 3
+#export RSYSLOG_DEBUGLOG="log2"
+generate_conf
+add_conf '
+# then SENDER sends to this port (not tcpflood!)
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="'$PORT_RCVR'")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" ./'$RSYSLOG_OUT_LOG';outfmt
+'
+startup
+echo waiting for sender to drain queue [may need a short while]
+wait_queueempty 2
+ls -l ${RSYSLOG_DYNNAME}.spool
+OLDFILESIZE=$(stat -c%s ${RSYSLOG_DYNNAME}.spool/mainq.00000001)
+echo file size to expect is $OLDFILESIZE
+
+
+#
+# Step 4: send new data. Queue files are not permitted to grow now
+# (but one file continuous to exist).
+#
+echo step 4
+injectmsg2 11001 10
+wait_queueempty 2
+
+# at this point, the queue file shall not have grown. Note
+# that we MUST NOT shut down the instance right now, because it
+# would clean up the queue files! So we need to do our checks
+# first (here!).
+ls -l ${RSYSLOG_DYNNAME}.spool
+NEWFILESIZE=$(stat -c%s ${RSYSLOG_DYNNAME}.spool/mainq.00000001)
+if [ $NEWFILESIZE != $OLDFILESIZE ]
+then
+ echo file sizes do not match, expected $OLDFILESIZE, actual $NEWFILESIZE
+ echo this means that data has been written to the queue file where it
+ echo no longer should be written.
+ # abort will happen below, because we must ensure proper system shutdown
+ # HOWEVER, during actual testing it may be useful to do an exit here (so
+ # that e.g. the debug log is pointed right at the correct spot).
+ # exit 1
+fi
+
+#
+# We now do an extra test (so this is two in one ;)) to see if the DA
+# queue can be reactivated after its initial shutdown. In essence, we
+# redo steps 2 and 3.
+#
+# Step 5: stop receiver again, then send some more data, which then
+# needs to go into the queue.
+#
+echo step 5
+echo "*** done primary test *** now checking if DA can be restarted"
+shutdown_when_empty
+wait_shutdown
+
+injectmsg2 11011 10000
+sleep 1 # we need to wait, otherwise we may be so fast that the receiver
+# comes up before we have finally suspended the action
+get_mainqueuesize 2
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+#
+# Step 6: restart receiver, wait that the sender drains its queue
+#
+echo step 6
+startup
+echo waiting for sender to drain queue [may need a short while]
+wait_queueempty 2
+ls -l ${RSYSLOG_DYNNAME}.spool
+
+#
+# Queue file size checks done. Now it is time to terminate the system
+# and see if everything could be received (the usual check, done here
+# for completeness, more or less as a bonus).
+#
+shutdown_when_empty 2
+wait_shutdown 2
+
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# now abort test if we need to (due to filesize predicate)
+if [ $NEWFILESIZE != $OLDFILESIZE ]; then
+ error_exit 1
+fi
+# do the final check
+seq_check 1 21010 -m 100
+exit_test
diff --git a/tests/relp_tls_certificate_not_found.sh b/tests/relp_tls_certificate_not_found.sh
new file mode 100755
index 0000000..50f6518
--- /dev/null
+++ b/tests/relp_tls_certificate_not_found.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# add 2017-09-21 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+
+module(load="../plugins/omrelp/.libs/omrelp")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+ruleset(name="ruleset") {
+ action(type="omrelp" target="127.0.0.1" port="10514" tls="on" tls.authMode="name" tls.caCert="tls-certs/ca.pem" tls.myCert="tls-certs/fake-cert.pem" tls.myPrivKey="tls-certs/fake-key.pem" tls.permittedPeer=["rsyslog-test-root-ca"])
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+grep "certificate file tls-certs/fake-cert.pem.*No such file" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message from missing input file not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/rfc5424parser-sp_at_msg_start.sh b/tests/rfc5424parser-sp_at_msg_start.sh
new file mode 100755
index 0000000..5f927ad
--- /dev/null
+++ b/tests/rfc5424parser-sp_at_msg_start.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# checks that in RFC5424 mode SP at beginning of MSG part is properly handled
+# This file is part of the rsyslog project, released under ASL 2.0
+# rgerhards, 2019-05-17
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg%--END\n")
+
+if $syslogtag == "tag" then
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg literal '<13>1 2019-05-15T11:21:57+03:00 domain.tld tag - - - nosd-nosp'
+injectmsg literal '<13>1 2019-05-15T11:21:57+03:00 domain.tld tag - - [abc@123 a="b"] sd-nosp'
+injectmsg literal '<13>1 2019-05-15T11:21:57+03:00 domain.tld tag - - - nosd-sp'
+injectmsg literal '<13>1 2019-05-15T11:21:57+03:00 domain.tld tag - - [abc@123 a="b"] sd-sp'
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='nosd-nosp--END
+sd-nosp--END
+ nosd-sp--END
+ sd-sp--END'
+cmp_exact
+exit_test
diff --git a/tests/rfc5424parser.sh b/tests/rfc5424parser.sh
new file mode 100755
index 0000000..a1f2081
--- /dev/null
+++ b/tests/rfc5424parser.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+# rgerhards, 2013-11-22
+echo ===============================================================================
+echo \[rfc5424parser.sh\]: testing mmpstrucdata
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+if $msg contains "msgnum" then
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+sleep 1
+tcpflood -m100 -y
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 99
+exit_test
diff --git a/tests/rs-cnum.sh b/tests/rs-cnum.sh
new file mode 100755
index 0000000..ea092ef
--- /dev/null
+++ b/tests/rs-cnum.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# add 2018-04-04 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $!var = cnum(15*3);
+
+template(name="outfmt" type="string" string="-%$!var%-\n")
+:syslogtag, contains, "tag" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\""
+shutdown_when_empty
+wait_shutdown
+echo '-45-' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/rs-int2hex.sh b/tests/rs-int2hex.sh
new file mode 100755
index 0000000..c320c8b
--- /dev/null
+++ b/tests/rs-int2hex.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# add 2018-04-04 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $!var = int2hex(61);
+set $!var2 = int2hex(-13);
+
+template(name="outfmt" type="string" string="-%$!var%- -%$!var2%-\n")
+:syslogtag, contains, "tag" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\""
+shutdown_when_empty
+wait_shutdown
+echo '-3d- -fffffffffffffff3-' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/rs-substring.sh b/tests/rs-substring.sh
new file mode 100755
index 0000000..f101298
--- /dev/null
+++ b/tests/rs-substring.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# add 2018-04-04 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $!var = substring($msg, 3, 2);
+
+template(name="outfmt" type="string" string="-%$!var%-\n")
+:syslogtag, contains, "tag" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\""
+shutdown_when_empty
+wait_shutdown
+echo '-gn-' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/rs_optimizer_pri.sh b/tests/rs_optimizer_pri.sh
new file mode 100755
index 0000000..178e4e8
--- /dev/null
+++ b/tests/rs_optimizer_pri.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Test for the RainerScript optimizer, folding of
+# syslogfacility/priority-text to prifilt. Unfortunately, we cannot yet
+# automatically detect if the optimizer does not correctly fold, but we
+# can at least detect if it segfaults or otherwise creates incorrect code.
+# This file is part of the rsyslog project, released under ASL 2.0
+# rgerhards, 2013-11-20
+echo ===============================================================================
+echo \[rs_optimizer_pri.sh\]: testing RainerScript PRI optimizer
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+if $syslogfacility-text == "local4" then
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+sleep 1
+tcpflood -m100 # correct facility
+tcpflood -m100 -P175 # incorrect facility --> must be ignored
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 99
+exit_test
diff --git a/tests/rscript-config_enable-off-vg.sh b/tests/rscript-config_enable-off-vg.sh
new file mode 100755
index 0000000..900e926
--- /dev/null
+++ b/tests/rscript-config_enable-off-vg.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export DO_STOP=off
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum:" then {
+ if $msg contains "msgnum:00000000" then {
+ include(text="stop" config.enabled=`echo $DO_STOP`)
+ }
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup_vg
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+seq_check 0 9
+exit_test
diff --git a/tests/rscript-config_enable-on.sh b/tests/rscript-config_enable-on.sh
new file mode 100755
index 0000000..9b09d1b
--- /dev/null
+++ b/tests/rscript-config_enable-on.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# tests 'config.enabled="on"' -- default value is implicitly check
+# in all testbench tests and does not need its individual test
+# (actually it is here tested via template() and action() as well...
+# added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export DO_STOP=on
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum:" then {
+ if $msg contains "msgnum:00000000" then {
+ include(text="stop" config.enabled=`echo $DO_STOP`)
+ }
+ action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+seq_check 1 9
+exit_test
diff --git a/tests/rscript_backticks-vg.sh b/tests/rscript_backticks-vg.sh
new file mode 100755
index 0000000..56ab8fc
--- /dev/null
+++ b/tests/rscript_backticks-vg.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if `echo $DO_WORK` == "on" and $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+export DO_WORK=on
+startup_vg
+injectmsg 0 1000
+#tcpflood -m10
+shutdown_when_empty
+wait_shutdown_vg
+seq_check 0 999
+exit_test
diff --git a/tests/rscript_backticks_empty_envvar-vg.sh b/tests/rscript_backticks_empty_envvar-vg.sh
new file mode 100755
index 0000000..95d2038
--- /dev/null
+++ b/tests/rscript_backticks_empty_envvar-vg.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# added 2018-11-02 by rgerhards
+# see also https://github.com/rsyslog/rsyslog/issues/3006
+# released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+if `echo $DOES_NOT_EXIST` == "" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup_vg
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+content_check --regex "rsyslogd: .*start"
+exit_test
diff --git a/tests/rscript_bare_var_root-empty.sh b/tests/rscript_bare_var_root-empty.sh
new file mode 100755
index 0000000..48c8573
--- /dev/null
+++ b/tests/rscript_bare_var_root-empty.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# addd 2018-01-01 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="empty-%$!%-\n")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="rs")
+
+ruleset(name="rs") {
+ set $. = $!;
+ set $! = $.;
+
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='empty--'
+echo "$EXPECTED" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "FAIL: $RSYSLOG_OUT_LOG content invalid:"
+ cat $RSYSLOG_OUT_LOG
+ echo "Expected:"
+ echo "$EXPECTED"
+ error_exit 1
+fi;
+exit_test
diff --git a/tests/rscript_bare_var_root.sh b/tests/rscript_bare_var_root.sh
new file mode 100755
index 0000000..c7af208
--- /dev/null
+++ b/tests/rscript_bare_var_root.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# addd 2018-01-01 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!%\n")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="rs")
+
+ruleset(name="rs") {
+ set $!a = "TEST1";
+ set $.a = "TEST-overwritten";
+ set $! = $.;
+
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='{ "a": "TEST-overwritten" }'
+echo "$EXPECTED" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "FAIL: $RSYSLOG_OUT_LOG content invalid:"
+ cat $RSYSLOG_OUT_LOG
+ echo "Expected:"
+ echo "$EXPECTED"
+ error_exit 1
+fi;
+exit_test
diff --git a/tests/rscript_compare-common.sh b/tests/rscript_compare-common.sh
new file mode 100755
index 0000000..71810c6
--- /dev/null
+++ b/tests/rscript_compare-common.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# added by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!result")
+ constant(value="\n")
+}
+set $!lower_nr = '$LOWER_VAL';
+set $!higher_nr = '$HIGHER_VAL';
+
+if $!lower_nr <= $!higher_nr
+ then { set $!result = "<= RIGHT"; }
+ else { set $!result = "<= WRONG"; }
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+
+if $!lower_nr < $!higher_nr
+ then { set $!result = "< RIGHT"; }
+ else { set $!result = "< WRONG"; }
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+
+if $!higher_nr >= $!lower_nr
+ then { set $!result = ">= RIGHT"; }
+ else { set $!result = ">= WRONG"; }
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+
+if $!higher_nr > $!lower_nr
+ then { set $!result = "> RIGHT"; }
+ else { set $!result = "> WRONG"; }
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+
+if $!higher_nr != $!lower_nr
+ then { set $!result = "!= RIGHT"; }
+ else { set $!result = "!= WRONG"; }
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+
+if $!higher_nr == $!lower_nr
+ then { set $!result = "== WRONG"; }
+ else { set $!result = "== RIGHT"; }
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check '<= RIGHT'
+content_check '>= RIGHT'
+content_check '!= RIGHT'
+content_check '== RIGHT'
+content_check '< RIGHT'
+content_check '> RIGHT'
+exit_test
diff --git a/tests/rscript_compare_num-num-vg.sh b/tests/rscript_compare_num-num-vg.sh
new file mode 100755
index 0000000..f08a92d
--- /dev/null
+++ b/tests/rscript_compare_num-num-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export LOWER_VAL='1'
+export HIGHER_VAL='2'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_num-num.sh b/tests/rscript_compare_num-num.sh
new file mode 100755
index 0000000..c3a75d8
--- /dev/null
+++ b/tests/rscript_compare_num-num.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export LOWER_VAL='1'
+export HIGHER_VAL='2'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_num-numstr-vg.sh b/tests/rscript_compare_num-numstr-vg.sh
new file mode 100755
index 0000000..889f535
--- /dev/null
+++ b/tests/rscript_compare_num-numstr-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export LOWER_VAL='1'
+export HIGHER_VAL='"2"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_num-numstr.sh b/tests/rscript_compare_num-numstr.sh
new file mode 100755
index 0000000..be510b1
--- /dev/null
+++ b/tests/rscript_compare_num-numstr.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export LOWER_VAL='1'
+export HIGHER_VAL='"2"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_num-str-vg.sh b/tests/rscript_compare_num-str-vg.sh
new file mode 100755
index 0000000..334a6b2
--- /dev/null
+++ b/tests/rscript_compare_num-str-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export LOWER_VAL='1'
+export HIGHER_VAL='"b"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_num-str.sh b/tests/rscript_compare_num-str.sh
new file mode 100755
index 0000000..5f2bc87
--- /dev/null
+++ b/tests/rscript_compare_num-str.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export LOWER_VAL='1'
+export HIGHER_VAL='"b"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_numstr-num-vg.sh b/tests/rscript_compare_numstr-num-vg.sh
new file mode 100755
index 0000000..32f3686
--- /dev/null
+++ b/tests/rscript_compare_numstr-num-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export LOWER_VAL='"1"'
+export HIGHER_VAL='2'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_numstr-num.sh b/tests/rscript_compare_numstr-num.sh
new file mode 100755
index 0000000..31ec55e
--- /dev/null
+++ b/tests/rscript_compare_numstr-num.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export LOWER_VAL='"1"'
+export HIGHER_VAL='2'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_numstr-numstr-vg.sh b/tests/rscript_compare_numstr-numstr-vg.sh
new file mode 100755
index 0000000..6663f21
--- /dev/null
+++ b/tests/rscript_compare_numstr-numstr-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export LOWER_VAL='"1"'
+export HIGHER_VAL='"2"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_numstr-numstr.sh b/tests/rscript_compare_numstr-numstr.sh
new file mode 100755
index 0000000..b58fe78
--- /dev/null
+++ b/tests/rscript_compare_numstr-numstr.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export LOWER_VAL='"1"'
+export HIGHER_VAL='"2"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_numstr-str-vg.sh b/tests/rscript_compare_numstr-str-vg.sh
new file mode 100755
index 0000000..82d727b
--- /dev/null
+++ b/tests/rscript_compare_numstr-str-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export LOWER_VAL='"1"'
+export HIGHER_VAL='"abc"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_numstr-str.sh b/tests/rscript_compare_numstr-str.sh
new file mode 100755
index 0000000..509e36f
--- /dev/null
+++ b/tests/rscript_compare_numstr-str.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export LOWER_VAL='"1"'
+export HIGHER_VAL='"abc"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_str-num-vg.sh b/tests/rscript_compare_str-num-vg.sh
new file mode 100755
index 0000000..fe5e8e6
--- /dev/null
+++ b/tests/rscript_compare_str-num-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export LOWER_VAL='"-"'
+export HIGHER_VAL='1'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_str-num.sh b/tests/rscript_compare_str-num.sh
new file mode 100755
index 0000000..5c1e186
--- /dev/null
+++ b/tests/rscript_compare_str-num.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export LOWER_VAL='"-"'
+export HIGHER_VAL='1'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_str-numstr-vg.sh b/tests/rscript_compare_str-numstr-vg.sh
new file mode 100755
index 0000000..3c83884
--- /dev/null
+++ b/tests/rscript_compare_str-numstr-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export LOWER_VAL='"-"'
+export HIGHER_VAL='"2"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_str-numstr.sh b/tests/rscript_compare_str-numstr.sh
new file mode 100755
index 0000000..abffeed
--- /dev/null
+++ b/tests/rscript_compare_str-numstr.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export LOWER_VAL='"-"'
+export HIGHER_VAL='"2"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_str-str-vg.sh b/tests/rscript_compare_str-str-vg.sh
new file mode 100755
index 0000000..21a27a3
--- /dev/null
+++ b/tests/rscript_compare_str-str-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export LOWER_VAL='"a"'
+export HIGHER_VAL='"b"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_compare_str-str.sh b/tests/rscript_compare_str-str.sh
new file mode 100755
index 0000000..a7d8baf
--- /dev/null
+++ b/tests/rscript_compare_str-str.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export LOWER_VAL='"a"'
+export HIGHER_VAL='"b"'
+source ${srcdir:-.}/rscript_compare-common.sh
diff --git a/tests/rscript_contains.sh b/tests/rscript_contains.sh
new file mode 100755
index 0000000..7352946
--- /dev/null
+++ b/tests/rscript_contains.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# added 2012-09-14 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$template outfmt,"%msg:F,58:2%\n"
+if $msg contains "msgnum" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/rscript_eq.sh b/tests/rscript_eq.sh
new file mode 100755
index 0000000..150f88e
--- /dev/null
+++ b/tests/rscript_eq.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_eq.sh\]: testing rainerscript EQ statement
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ if $!usr!msgnum == "00005000" or
+ $!usr!msgnum == "00005001" or
+ $!usr!msgnum == "00005002" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 8000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 5000 5002
+exit_test
diff --git a/tests/rscript_eq_var.sh b/tests/rscript_eq_var.sh
new file mode 100755
index 0000000..987ab48
--- /dev/null
+++ b/tests/rscript_eq_var.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_eq.sh\]: testing rainerscript EQ statement comparing two variables
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+set $!var1 = "value";
+set $!var2 = "value";
+if $!var1 == $!var2 then {
+ set $!var2 = "bad";
+ if $!var1 == $!var2 then {
+ # Failure
+ stop
+ } else {
+ unset $!var1;
+ unset $!var2;
+ }
+} else {
+ # Failure
+ stop
+}
+set $.var1 = "value";
+set $.var2 = "value";
+if $.var1 == $.var2 then {
+ set $.var2 = "bad";
+ if $.var1 == $.var2 then {
+ # Failure
+ stop
+ } else {
+ unset $.var1;
+ unset $.var2;
+ }
+} else {
+ # Failure
+ stop
+}
+set $/var1 = "value";
+set $/var2 = "value";
+if $/var1 == $/var2 then {
+ set $/var2 = "bad";
+ if $/var1 == $/var2 then {
+ # Failure
+ stop
+ } else {
+ unset $/var1;
+ unset $/var2;
+ }
+} else {
+ # Failure
+ stop
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 1
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 0
+exit_test
diff --git a/tests/rscript_exists-not1.sh b/tests/rscript_exists-not1.sh
new file mode 100755
index 0000000..90c433c
--- /dev/null
+++ b/tests/rscript_exists-not1.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# add 2020-10-02 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%!result%\n")
+# ensure that in this test there is NO variable define at all
+if $msg contains "msgnum" then {
+ if exists($!p1!p2!val) then
+ set $!result = "on";
+ else
+ set $!result = "off";
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+ }
+'
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='off'
+cmp_exact
+exit_test
diff --git a/tests/rscript_exists-not2.sh b/tests/rscript_exists-not2.sh
new file mode 100755
index 0000000..2044c3e
--- /dev/null
+++ b/tests/rscript_exists-not2.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# add 2020-10-02 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%!result%\n")
+set $!somevar = "test"; # this makes matters a bit more complicated
+if $msg contains "msgnum" then {
+ if exists($!p1!p2!val) then
+ set $!result = "on";
+ else
+ set $!result = "off";
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+ }
+'
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='off'
+cmp_exact
+exit_test
diff --git a/tests/rscript_exists-not3.sh b/tests/rscript_exists-not3.sh
new file mode 100755
index 0000000..9b90aa0
--- /dev/null
+++ b/tests/rscript_exists-not3.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# add 2020-10-02 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%!result%\n")
+# ensure that in this test there is NO variable define at all
+if $msg contains "msgnum" then {
+ if exists($.p1!p2!val) then
+ set $!result = "on";
+ else
+ set $!result = "off";
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+ }
+'
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='off'
+cmp_exact
+exit_test
diff --git a/tests/rscript_exists-not4.sh b/tests/rscript_exists-not4.sh
new file mode 100755
index 0000000..df4415e
--- /dev/null
+++ b/tests/rscript_exists-not4.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# add 2020-10-02 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%!result%\n")
+set $.somevar = "test"; # this makes matters a bit more complicated
+if $msg contains "msgnum" then {
+ if not exists($.p1!p2!val) then
+ set $!result = "off";
+ else
+ set $!result = "on";
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+ }
+'
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='off'
+cmp_exact
+exit_test
diff --git a/tests/rscript_exists-yes.sh b/tests/rscript_exists-yes.sh
new file mode 100755
index 0000000..ba8805e
--- /dev/null
+++ b/tests/rscript_exists-yes.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# add 2020-10-02 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%!result%\n")
+set $!p1!p2!val="yes!";
+if $msg contains "msgnum" then {
+ if exists($!p1!p2!val) then
+ set $!result = "on";
+ else
+ set $!result = "off";
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+ }
+'
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='on'
+cmp_exact
+exit_test
diff --git a/tests/rscript_exists-yes2.sh b/tests/rscript_exists-yes2.sh
new file mode 100755
index 0000000..ebd3445
--- /dev/null
+++ b/tests/rscript_exists-yes2.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# add 2020-10-02 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%!result%\n")
+set $.p1!p2!val="yes!";
+if $msg contains "msgnum" then {
+ if exists($.p1!p2!val) then
+ set $!result = "on";
+ else
+ set $!result = "off";
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+ }
+'
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='on'
+cmp_exact
+exit_test
diff --git a/tests/rscript_field-vg.sh b/tests/rscript_field-vg.sh
new file mode 100755
index 0000000..ac593ce
--- /dev/null
+++ b/tests/rscript_field-vg.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# added 2012-09-20 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[rscript_field-vg.sh\]: testing rainerscript field\(\) function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup_vg
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+seq_check 0 4999
+exit_test
diff --git a/tests/rscript_field.sh b/tests/rscript_field.sh
new file mode 100755
index 0000000..b16fca1
--- /dev/null
+++ b/tests/rscript_field.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# added 2012-09-20 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_field.sh\]: testing rainerscript field\(\) function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/rscript_format_time.sh b/tests/rscript_format_time.sh
new file mode 100755
index 0000000..b0f53d7
--- /dev/null
+++ b/tests/rscript_format_time.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# Added 2017-10-03 by Stephen Workman, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omstdout/.libs/omstdout")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# $DebugLevel 2
+
+set $!datetime!rfc3164 = format_time(1507165811, "date-rfc3164");
+set $!datetime!rfc3339 = format_time(1507165811, "date-rfc3339");
+
+set $!datetime!rfc3164Neg = format_time(-1507165811, "date-rfc3164");
+set $!datetime!rfc3339Neg = format_time(-1507165811, "date-rfc3339");
+
+set $!datetime!str1 = format_time("1507165811", "date-rfc3339");
+set $!datetime!strinv1 = format_time("ABC", "date-rfc3339");
+
+template(name="outfmt" type="string" string="%!datetime%\n")
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+local4.* :omstdout:;outfmt
+'
+
+startup
+tcpflood -m1 -y | sed 's|\r||'
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='{ "rfc3164": "Oct 5 01:10:11", "rfc3339": "2017-10-05T01:10:11Z", "rfc3164Neg": "Mar 29 22:49:49", "rfc3339Neg": "1922-03-29T22:49:49Z", "str1": "2017-10-05T01:10:11Z", "strinv1": "ABC" }'
+
+# FreeBSD's cmp does not support reading from STDIN
+cmp <(echo "$EXPECTED") $RSYSLOG_OUT_LOG
+
+if [[ $? -ne 0 ]]; then
+ printf 'Invalid function output detected!\n'
+ printf "Expected: $EXPECTED\n"
+ printf 'Got: '
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/rscript_ge.sh b/tests/rscript_ge.sh
new file mode 100755
index 0000000..489daa2
--- /dev/null
+++ b/tests/rscript_ge.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_ge.sh\]: testing rainerscript GE statement
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ if $!usr!msgnum >= "00005000" then
+ stop
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 8000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/rscript_ge_var.sh b/tests/rscript_ge_var.sh
new file mode 100755
index 0000000..f71e1d4
--- /dev/null
+++ b/tests/rscript_ge_var.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_ge.sh\]: testing rainerscript GE statement for two JSON variables
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+set $!var1 = "42";
+set $!var2 = "42";
+set $!var3 = "41";
+if $!var1 >= $!var2 and $!var1 >= $!var3 then {
+ if $!var3 >= $!var1 then {
+ # Failure
+ stop
+ } else {
+ unset $!var1;
+ unset $!var2;
+ unset $!var3;
+ }
+} else {
+ # Failure
+ stop
+}
+set $.var1 = "42";
+set $.var2 = "42";
+set $.var3 = "41";
+if $.var1 >= $.var2 and $.var1 >= $.var3 then {
+ if $.var3 >= $.var1 then {
+ # Failure
+ stop
+ } else {
+ unset $.var1;
+ unset $.var2;
+ unset $.var3;
+ }
+} else {
+ # Failure
+ stop
+}
+set $/var1 = "42";
+set $/var2 = "42";
+set $/var3 = "41";
+if $/var1 >= $/var2 and $/var1 >= $/var3 then {
+ if $/var3 >= $/var1 then {
+ # Failure
+ stop
+ } else {
+ unset $/var1;
+ unset $/var2;
+ unset $/var3;
+ }
+} else {
+ # Failure
+ stop
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 1
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 0
+exit_test
diff --git a/tests/rscript_get_property-vg.sh b/tests/rscript_get_property-vg.sh
new file mode 100755
index 0000000..5832373
--- /dev/null
+++ b/tests/rscript_get_property-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/rscript_get_property.sh
diff --git a/tests/rscript_get_property.sh b/tests/rscript_get_property.sh
new file mode 100755
index 0000000..03302bc
--- /dev/null
+++ b/tests/rscript_get_property.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="string" string="%$!%\n")
+template(name="outlocal" type="string" string="%$.%\n")
+
+if $msg contains "msgnum" then {
+ set $.ret = parse_json("{\"offsets\": [ { \"a\": 9, \"b\": 0, \"c\": \"boo\", \"d\": null },\
+ { \"a\": 9, \"b\": 3, \"c\": null, \"d\": null } ],\
+ \"booltest\": true,\
+ \"int64\": 1234567890,\
+ \"nulltest\": null,\
+ \"double\": 12345.67890,\
+ \"foo\": 3, \"bar\": 28 }", "\$!parsed");
+
+ if $.ret == 0 then {
+ # set up some locals
+ set $!foo!bar = 3;
+ set $.index = "1";
+ set $.test = "a";
+
+ # evaluate
+ set $.res1 = get_property($!parsed!offsets, $.index);
+ set $.res2 = get_property($!parsed!offsets[1], $.test);
+ reset $.test = "bar";
+ set $.res3 = get_property($!foo, $.test);
+ reset $.index = 5;
+ set $.res4 = get_property($!parsed!offsets, $.index);
+ set $.key = "test";
+ set $.res5 = get_property($., $.key);
+ reset $.key = "foo";
+ set $.res6 = get_property($!, $.key);
+ set $.res7 = get_property($!foo, "bar");
+ reset $.key = "ar";
+ set $.res8 = get_property($!foo, "b" & $.key);
+ set $.res9 = get_property($!foo!bar, "");
+ reset $.key = "";
+ set $.res10 = get_property($!foo!bar, $.key);
+ set $.res11 = get_property($!parsed!booltest, "");
+ reset $.key = "int64";
+ set $.res12 = get_property($!parsed, $.key);
+ reset $.key = "nulltest";
+ set $.res13 = get_property($!parsed, $.key);
+ reset $.key = "double";
+ set $.res14 = get_property($!parsed, $.key);
+ set $.res15 = get_property($msg, "");
+ set $.res16 = get_property("string literal", "");
+
+ # output result
+ unset $.key;
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outlocal")
+ }
+}
+'
+
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+
+EXPECTED='{ "parsed": { "offsets": [ { "a": 9, "b": 0, "c": "boo", "d": null }, { "a": 9, "b": 3, "c": null, "d": null } ], "booltest": true, "int64": 1234567890, "nulltest": null, "double": 12345.67890, "foo": 3, "bar": 28 }, "foo": { "bar": 3 } }
+{ "ret": 0, "index": 5, "test": "bar", "res1": { "a": 9, "b": 3, "c": null, "d": null }, "res2": 9, "res3": 3, "res4": "", "res5": "bar", "res6": { "bar": 3 }, "res7": 3, "res8": 3, "res9": 3, "res10": 3, "res11": 1, "res12": 1234567890, "res13": "", "res14": 12345.678900000001, "res15": " msgnum:00000000:", "res16": "" }'
+cmp_exact
+
+exit_test
diff --git a/tests/rscript_gt.sh b/tests/rscript_gt.sh
new file mode 100755
index 0000000..9559ca0
--- /dev/null
+++ b/tests/rscript_gt.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_gt.sh\]: testing rainerscript GT statement
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ if $!usr!msgnum > "00004999" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 8000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 5000 7999
+exit_test
diff --git a/tests/rscript_gt_var.sh b/tests/rscript_gt_var.sh
new file mode 100755
index 0000000..1553182
--- /dev/null
+++ b/tests/rscript_gt_var.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_gt.sh\]: testing rainerscript GT statement for two JSON variables
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+set $!var1 = "43";
+set $!var2 = "42";
+if $!var1 > $!var2 then {
+ if $!var2 > $!var1 then {
+ # Failure
+ stop
+ } else {
+ unset $!var1;
+ unset $!var2;
+ }
+} else {
+ # Failure
+ stop
+}
+set $.var1 = "43";
+set $.var2 = "42";
+if $.var1 > $.var2 then {
+ if $.var2 > $.var1 then {
+ # Failure
+ stop
+ } else {
+ unset $.var1;
+ unset $.var2;
+ }
+} else {
+ # Failure
+ stop
+}
+set $/var1 = "43";
+set $/var2 = "42";
+if $/var1 > $/var2 then {
+ if $/var2 > $/var1 then {
+ # Failure
+ stop
+ } else {
+ unset $/var1;
+ unset $/var2;
+ }
+} else {
+ # Failure
+ stop
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 1
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 0
+exit_test
diff --git a/tests/rscript_hash32-vg.sh b/tests/rscript_hash32-vg.sh
new file mode 100755
index 0000000..2114682
--- /dev/null
+++ b/tests/rscript_hash32-vg.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2018-02-07 by Harshvardhan Shrivastava
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \rscript_hash32.sh\]: test for hash32 and hash64mod script-function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$.hash_no_1% - %$.hash_no_2%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmhash/.libs/fmhash")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $.hash_no_1 = hash32("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e");
+set $.hash_no_2 = hash32mod("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e", 100);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+tcpflood -m 20
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+. $srcdir/diag.sh content-pattern-check "^\(746581550 - 50\|3889673532 - 32\)$"
+exit_test
diff --git a/tests/rscript_hash32.sh b/tests/rscript_hash32.sh
new file mode 100755
index 0000000..b4582de
--- /dev/null
+++ b/tests/rscript_hash32.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# added 2018-02-07 by Harshvardhan Shrivastava
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \rscript_hash32.sh\]: test for hash32 and hash64mod script-function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$.hash_no_1% - %$.hash_no_2%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmhash/.libs/fmhash")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $.hash_no_1 = hash32("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e");
+set $.hash_no_2 = hash32mod("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e", 100);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 20
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+. $srcdir/diag.sh content-pattern-check "^\(746581550 - 50\|3889673532 - 32\)$"
+exit_test
diff --git a/tests/rscript_hash64-vg.sh b/tests/rscript_hash64-vg.sh
new file mode 100755
index 0000000..13fb2ee
--- /dev/null
+++ b/tests/rscript_hash64-vg.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2018-02-07 by Harshvardhan Shrivastava
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \rscript_hash64.sh\]: test for hash64 and hash64mod script-function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$.hash_no_1% - %$.hash_no_2%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmhash/.libs/fmhash")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $.hash_no_1 = hash64("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e");
+set $.hash_no_2 = hash64mod("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e", 100);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+tcpflood -m 20
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+. $srcdir/diag.sh content-pattern-check "^\(-2574714428477944902 - 14\|-50452361579464591 - 25\)$"
+exit_test
diff --git a/tests/rscript_hash64.sh b/tests/rscript_hash64.sh
new file mode 100755
index 0000000..7b3e7c5
--- /dev/null
+++ b/tests/rscript_hash64.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# added 2018-02-07 by Harshvardhan Shrivastava
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \rscript_hash64.sh\]: test for hash64 and hash64mod script-function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$.hash_no_1% - %$.hash_no_2%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmhash/.libs/fmhash")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $.hash_no_1 = hash64("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e");
+set $.hash_no_2 = hash64mod("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e", 100);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 20
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+. $srcdir/diag.sh content-pattern-check "^\(-2574714428477944902 - 14\|-50452361579464591 - 25\)$"
+exit_test
diff --git a/tests/rscript_http_request-vg.sh b/tests/rscript_http_request-vg.sh
new file mode 100755
index 0000000..3584e47
--- /dev/null
+++ b/tests/rscript_http_request-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export TB_TEST_MAX_RUNTIME=1500
+source ${srcdir:-.}/rscript_http_request.sh
diff --git a/tests/rscript_http_request.sh b/tests/rscript_http_request.sh
new file mode 100755
index 0000000..0e46ade
--- /dev/null
+++ b/tests/rscript_http_request.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# add 2017-12-01 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+rsyslog_testbench_test_url_access http://testbench.rsyslog.com/testbench/echo-get.php
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/fmhttp/.libs/fmhttp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# for debugging the test itself:
+#template(name="outfmt" type="string" string="%$!%: :%$.%: %rawmsg%\n")
+template(name="outfmt" type="string" string="%$!%\n")
+
+if $msg contains "msgnum:" then {
+ set $.url = "http://testbench.rsyslog.com/testbench/echo-get.php?content=" & ltrim($msg);
+ set $!reply = http_request($.url);
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+tcpflood -m10
+wait_file_lines $RSYSLOG_OUT_LOG 10 200
+shutdown_when_empty
+wait_shutdown
+
+# check for things that look like http failures
+if grep -q "DOCTYPE" "$RSYSLOG_OUT_LOG" ; then
+ printf 'SKIP: looks like we have problems with the upstream http server:\n'
+ cat -n "$RSYSLOG_OUT_LOG"
+ printf '\n'
+ error_exit 177
+fi
+
+export EXPECTED='{ "reply": "msgnum:00000000:" }
+{ "reply": "msgnum:00000001:" }
+{ "reply": "msgnum:00000002:" }
+{ "reply": "msgnum:00000003:" }
+{ "reply": "msgnum:00000004:" }
+{ "reply": "msgnum:00000005:" }
+{ "reply": "msgnum:00000006:" }
+{ "reply": "msgnum:00000007:" }
+{ "reply": "msgnum:00000008:" }
+{ "reply": "msgnum:00000009:" }'
+cmp_exact $RSYSLOG_OUT_LOG
+exit_test
+
diff --git a/tests/rscript_int2Hex.sh b/tests/rscript_int2Hex.sh
new file mode 100755
index 0000000..9ff5e26
--- /dev/null
+++ b/tests/rscript_int2Hex.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# add 2017-02-09 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $!ip!v0 = int2hex("");
+set $!ip!v1 = int2hex("0");
+set $!ip!v2 = int2hex("1");
+set $!ip!v4 = int2hex("375894");
+set $!ip!v6 = int2hex("16");
+set $!ip!v8 = int2hex("4294967295");
+
+set $!ip!e1 = int2hex("a");
+
+template(name="outfmt" type="string" string="%!ip%\n")
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m1 -y
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='{ "v0": "0", "v1": "0", "v2": "1", "v4": "5bc56", "v6": "10", "v8": "ffffffff", "e1": "NAN" }'
+cmp_exact
+exit_test
diff --git a/tests/rscript_ipv42num.sh b/tests/rscript_ipv42num.sh
new file mode 100755
index 0000000..25a5a3d
--- /dev/null
+++ b/tests/rscript_ipv42num.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# add 2017-02-09 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# in pre 8.1907.0 versions of rsyslog the code was misspelled as
+# "ip42num" (missing "v"). We check this is still supported as alias
+set $!ip!v0 = ip42num("0.0.0.0");
+
+# use correct function name
+set $!ip!v1 = ipv42num("0.0.0.0");
+set $!ip!v2 = ipv42num("0.0.0.1");
+set $!ip!v3 = ipv42num("0.0.1.0");
+set $!ip!v4 = ipv42num("0.1.0.0");
+set $!ip!v5 = ipv42num("1.0.0.0");
+set $!ip!v6 = ipv42num("0.0.0.135");
+set $!ip!v7 = ipv42num("1.1.1.1");
+set $!ip!v8 = ipv42num("225.33.1.10");
+set $!ip!v9 = ipv42num("172.0.0.1");
+set $!ip!v10 = ipv42num("255.255.255.255");
+set $!ip!v11 = ipv42num("1.0.3.45 ");
+set $!ip!v12 = ipv42num(" 0.0.0.1");
+set $!ip!v13 = ipv42num(" 0.0.0.1 ");
+
+set $!ip!e1 = ipv42num("a");
+set $!ip!e2 = ipv42num("");
+set $!ip!e3 = ipv42num("123.4.6.*");
+set $!ip!e4 = ipv42num("172.0.0.1.");
+set $!ip!e5 = ipv42num("172.0.0..1");
+set $!ip!e6 = ipv42num(".172.0.0.1");
+set $!ip!e7 = ipv42num(".17 2.0.0.1");
+
+
+template(name="outfmt" type="string" string="%!ip%\n")
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m1 -y
+shutdown_when_empty
+wait_shutdown
+echo '{ "v0": 0, "v1": 0, "v2": 1, "v3": 256, "v4": 65536, "v5": 16777216, "v6": 135, "v7": 16843009, "v8": 3777036554, "v9": 2885681153, "v10": 4294967295, "v11": 16778029, "v12": 1, "v13": 1, "e1": -1, "e2": -1, "e3": -1, "e4": -1, "e5": -1, "e6": -1, "e7": -1 }' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid function output detected, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+exit_test
+
diff --git a/tests/rscript_is_time.sh b/tests/rscript_is_time.sh
new file mode 100755
index 0000000..d0ca09d
--- /dev/null
+++ b/tests/rscript_is_time.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+# Added 2017-12-16 by Stephen Workman, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omstdout/.libs/omstdout")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# $DebugLevel 2
+
+set $!result!date_auto_1 = is_time("Oct 5 01:10:11");
+set $!result!errno_date_auto_1 = script_error();
+set $!result!date_auto_2 = is_time("2017-10-05T01:10:11Z");
+set $!result!errno_date_auto_2 = script_error();
+set $!result!date_auto_3 = is_time("2017-10-05T01:10:11-03:00");
+set $!result!errno_date_auto_3 = script_error();
+set $!result!date_auto_4 = is_time("90210");
+set $!result!errno_date_auto_4 = script_error();
+
+set $!result!date_explicit_1 = is_time("Oct 5 01:10:11", "date-rfc3164");
+set $!result!errno_date_explicit_1 = script_error();
+set $!result!date_explicit_2 = is_time("2017-10-05T01:10:11Z", "date-rfc3339");
+set $!result!errno_date_explicit_2 = script_error();
+set $!result!date_explicit_3 = is_time("2017-10-05T01:10:11+04:00", "date-rfc3339");
+set $!result!errno_date_explicit_3 = script_error();
+set $!result!date_explicit_4 = is_time(90210, "date-unix");
+set $!result!errno_date_explicit_4 = script_error();
+set $!result!date_explicit_5 = is_time(-88, "date-unix");
+set $!result!errno_date_explicit_5 = script_error();
+set $!result!date_explicit_6 = is_time(0, "date-unix");
+set $!result!errno_date_explicit_6 = script_error();
+set $!result!date_explicit_7 = is_time("90210", "date-unix");
+set $!result!errno_date_explicit_7 = script_error();
+set $!result!date_explicit_8 = is_time("-88", "date-unix");
+set $!result!errno_date_explicit_8 = script_error();
+
+# Bad dates
+set $!result!date_fail_1 = is_time("Oct 88 01:10:11");
+set $!result!errno_date_fail_1 = script_error();
+set $!result!date_fail_2 = is_time("not at all a date");
+set $!result!errno_date_fail_2 = script_error();
+
+# Wrong format
+set $!result!date_fail_3 = is_time("Oct 5 01:10:11", "date-rfc3339");
+set $!result!errno_date_fail_3 = script_error();
+set $!result!date_fail_4 = is_time("2017-10-05T01:10:11Z", "date-rfc3164");
+set $!result!errno_date_fail_4 = script_error();
+set $!result!date_fail_5 = is_time("Oct 5 01:10:11", "date-unix");
+set $!result!errno_date_fail_5 = script_error();
+
+# Invalid format
+set $!result!date_fail_6 = is_time("90210", "date-spoonix");
+set $!result!errno_date_fail_6 = script_error();
+
+template(name="outfmt" type="string" string="%!result%\n")
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+local4.* :omstdout:;outfmt
+'
+
+startup
+tcpflood -m1 -y
+shutdown_when_empty
+wait_shutdown
+
+# Our fixed and calculated expected results
+export EXPECTED='{ "date_auto_1": 1, "errno_date_auto_1": 0, "date_auto_2": 1, "errno_date_auto_2": 0, "date_auto_3": 1, "errno_date_auto_3": 0, "date_auto_4": 1, "errno_date_auto_4": 0, "date_explicit_1": 1, "errno_date_explicit_1": 0, "date_explicit_2": 1, "errno_date_explicit_2": 0, "date_explicit_3": 1, "errno_date_explicit_3": 0, "date_explicit_4": 1, "errno_date_explicit_4": 0, "date_explicit_5": 1, "errno_date_explicit_5": 0, "date_explicit_6": 1, "errno_date_explicit_6": 0, "date_explicit_7": 1, "errno_date_explicit_7": 0, "date_explicit_8": 1, "errno_date_explicit_8": 0, "date_fail_1": 0, "errno_date_fail_1": 1, "date_fail_2": 0, "errno_date_fail_2": 1, "date_fail_3": 0, "errno_date_fail_3": 1, "date_fail_4": 0, "errno_date_fail_4": 1, "date_fail_5": 0, "errno_date_fail_5": 1, "date_fail_6": 0, "errno_date_fail_6": 1 }'
+
+# FreeBSD's cmp does not support reading from STDIN
+cmp <(echo "$EXPECTED") $RSYSLOG_OUT_LOG
+
+if [[ $? -ne 0 ]]; then
+ printf "Invalid function output detected!\n"
+ printf "Expected: $EXPECTED\n"
+ printf "Got: "
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/rscript_le.sh b/tests/rscript_le.sh
new file mode 100755
index 0000000..406a0a3
--- /dev/null
+++ b/tests/rscript_le.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_le.sh\]: testing rainerscript LE statement
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ if $!usr!msgnum <= "00005000" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 8000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 5000
+exit_test
diff --git a/tests/rscript_le_var.sh b/tests/rscript_le_var.sh
new file mode 100755
index 0000000..6abc933
--- /dev/null
+++ b/tests/rscript_le_var.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_le.sh\]: testing rainerscript LE statement for two JSON variables
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+set $!var1 = "42";
+set $!var2 = "42";
+set $!var3 = "43";
+if $!var1 <= $!var2 and $!var1 <= $!var3 then {
+ if $!var3 <= $!var1 then {
+ # Failure
+ stop
+ } else {
+ unset $!var1;
+ unset $!var2;
+ unset $!var3;
+ }
+} else {
+ # Failure
+ stop
+}
+set $.var1 = "42";
+set $.var2 = "42";
+set $.var3 = "43";
+if $.var1 <= $.var2 and $.var1 <= $.var3 then {
+ if $.var3 <= $.var1 then {
+ # Failure
+ stop
+ } else {
+ unset $.var1;
+ unset $.var2;
+ unset $.var3;
+ }
+} else {
+ # Failure
+ stop
+}
+set $/var1 = "42";
+set $/var2 = "42";
+set $/var3 = "43";
+if $/var1 <= $/var2 and $/var1 <= $/var3 then {
+ if $/var3 <= $/var1 then {
+ # Failure
+ stop
+ } else {
+ unset $/var1;
+ unset $/var2;
+ unset $/var3;
+ }
+} else {
+ # Failure
+ stop
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 1
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 0
+exit_test
diff --git a/tests/rscript_lt.sh b/tests/rscript_lt.sh
new file mode 100755
index 0000000..e861f74
--- /dev/null
+++ b/tests/rscript_lt.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_lt.sh\]: testing rainerscript LT statement
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ if $!usr!msgnum < "00005000" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 8000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/rscript_lt_var.sh b/tests/rscript_lt_var.sh
new file mode 100755
index 0000000..9514a6e
--- /dev/null
+++ b/tests/rscript_lt_var.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_lt.sh\]: testing rainerscript LT statement for two JSON variables
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+set $!var1 = "41";
+set $!var2 = "42";
+if $!var1 < $!var2 then {
+ if $!var2 < $!var1 then {
+ # Failure
+ stop
+ } else {
+ unset $!var1;
+ unset $!var2;
+ }
+} else {
+ # Failure
+ stop
+}
+set $.var1 = "41";
+set $.var2 = "42";
+if $.var1 < $.var2 then {
+ if $.var2 < $.var1 then {
+ # Failure
+ stop
+ } else {
+ unset $.var1;
+ unset $.var2;
+ }
+} else {
+ # Failure
+ stop
+}
+set $/var1 = "41";
+set $/var2 = "42";
+if $/var1 < $/var2 then {
+ if $/var2 < $/var1 then {
+ # Failure
+ stop
+ } else {
+ unset $/var1;
+ unset $/var2;
+ }
+} else {
+ # Failure
+ stop
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 1
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 0
+exit_test
diff --git a/tests/rscript_ne.sh b/tests/rscript_ne.sh
new file mode 100755
index 0000000..21260a2
--- /dev/null
+++ b/tests/rscript_ne.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_ne.sh\]: testing rainerscript NE statement
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ if $!usr!msgnum != "00005000" and
+ $!usr!msgnum != "00005001" and
+ $!usr!msgnum != "00005002" then
+ set $!usr!write = 0;
+ else
+ set $!usr!write = 1;
+ if $!usr!write == 1 then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 8000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 5000 5002
+exit_test
diff --git a/tests/rscript_ne_var.sh b/tests/rscript_ne_var.sh
new file mode 100755
index 0000000..bbf8664
--- /dev/null
+++ b/tests/rscript_ne_var.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+# added 2014-01-17 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_ne.sh\]: testing rainerscript NE statement for two JSON variables
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+set $!var1 = "value1";
+set $!var2 = "value2";
+if $!var1 != $!var2 then {
+ set $!var1 = "value";
+ set $!var2 = "value";
+ if $!var1 != $!var2 then {
+ # Failure
+ stop
+ } else {
+ unset $!var1;
+ unset $!var2;
+ }
+} else {
+ # Failure
+ stop
+}
+set $.var1 = "value1";
+set $.var2 = "value2";
+if $.var1 != $.var2 then {
+ set $.var1 = "value";
+ set $.var2 = "value";
+ if $.var1 != $.var2 then {
+ # Failure
+ stop
+ } else {
+ unset $.var1;
+ unset $.var2;
+ }
+} else {
+ # Failure
+ stop
+}
+set $/var1 = "value1";
+set $/var2 = "value2";
+if $/var1 != $/var2 then {
+ set $/var1 = "value";
+ set $/var2 = "value";
+ if $/var1 != $/var2 then {
+ # Failure
+ stop
+ } else {
+ unset $/var1;
+ unset $/var2;
+ }
+} else {
+ # Failure
+ stop
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 1
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 0
+exit_test
diff --git a/tests/rscript_num2ipv4.sh b/tests/rscript_num2ipv4.sh
new file mode 100755
index 0000000..9be21f2
--- /dev/null
+++ b/tests/rscript_num2ipv4.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# add 2017-02-09 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/fmhttp/.libs/fmhttp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $!ip!v0 = num2ipv4("");
+set $!ip!v1 = num2ipv4("0");
+set $!ip!v2 = num2ipv4("1");
+set $!ip!v3 = num2ipv4("256");
+set $!ip!v4 = num2ipv4("65536");
+set $!ip!v5 = num2ipv4("16777216");
+set $!ip!v6 = num2ipv4("135");
+set $!ip!v7 = num2ipv4("16843009");
+set $!ip!v8 = num2ipv4("3777036554");
+set $!ip!v9 = num2ipv4("2885681153");
+set $!ip!v10 = num2ipv4("4294967295");
+
+set $!ip!e1 = num2ipv4("a");
+set $!ip!e2 = num2ipv4("-123");
+set $!ip!e3 = num2ipv4("1725464567890");
+set $!ip!e4 = num2ipv4("4294967296");
+set $!ip!e5 = num2ipv4("2839.");
+
+
+template(name="outfmt" type="string" string="%!ip%\n")
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m1 -y
+shutdown_when_empty
+wait_shutdown
+echo '{ "v0": "0.0.0.0", "v1": "0.0.0.0", "v2": "0.0.0.1", "v3": "0.0.1.0", "v4": "0.1.0.0", "v5": "1.0.0.0", "v6": "0.0.0.135", "v7": "1.1.1.1", "v8": "225.33.1.10", "v9": "172.0.0.1", "v10": "255.255.255.255", "e1": "-1", "e2": "-1", "e3": "-1", "e4": "-1", "e5": "-1" }' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid function output detected, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+exit_test
diff --git a/tests/rscript_number_comparison_LE-vg.sh b/tests/rscript_number_comparison_LE-vg.sh
new file mode 100755
index 0000000..5493137
--- /dev/null
+++ b/tests/rscript_number_comparison_LE-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/rscript_number_comparison_LE.sh
diff --git a/tests/rscript_number_comparison_LE.sh b/tests/rscript_number_comparison_LE.sh
new file mode 100755
index 0000000..acb9865
--- /dev/null
+++ b/tests/rscript_number_comparison_LE.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# added by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!result")
+ constant(value="\n")
+}
+set $!lower_nr = 1111;
+set $!higher_nr = 2222;
+
+if $!lower_nr <= $!higher_nr
+ then { set $!result = "RIGHT"; }
+ else { set $!result = "WRONG"; }
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check 'RIGHT'
+exit_test
diff --git a/tests/rscript_number_comparison_LT.sh b/tests/rscript_number_comparison_LT.sh
new file mode 100755
index 0000000..5cb729a
--- /dev/null
+++ b/tests/rscript_number_comparison_LT.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# added 2022-01-27 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!result")
+ constant(value="\n")
+}
+set $!lower_nr = 1111;
+set $!higher_nr = 2222;
+
+if $!higher_nr < $!lower_nr
+ then { set $!result = "WRONG"; }
+ else { set $!result = "RIGHT"; }
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check 'RIGHT'
+exit_test
diff --git a/tests/rscript_optimizer1.sh b/tests/rscript_optimizer1.sh
new file mode 100755
index 0000000..342f62b
--- /dev/null
+++ b/tests/rscript_optimizer1.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# added 2012-09-20 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_optimizer1.sh\]: testing rainerscript optimizer
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="msg" field.delimiter="58" field.number="2")
+ constant(value="\n")
+}
+
+/* tcpflood uses local4.=debug */
+if prifilt("syslog.*") then
+ stop # it actually does not matter what we do here
+else
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/rscript_parse_json-vg.sh b/tests/rscript_parse_json-vg.sh
new file mode 100755
index 0000000..275ca63
--- /dev/null
+++ b/tests/rscript_parse_json-vg.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# Added 2017-12-09 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="string" string="%$!%\n")
+
+local4.* {
+ set $.ret = parse_json("{ \"c1\":\"data\" }", "\$!parsed");
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+
+startup_vg
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+
+export EXPECTED='{ "parsed": { "c1": "data" } }'
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/rscript_parse_json.sh b/tests/rscript_parse_json.sh
new file mode 100755
index 0000000..db7bc22
--- /dev/null
+++ b/tests/rscript_parse_json.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Added 2017-12-09 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="string" string="%$!%\n")
+
+local4.* {
+ set $.ret = parse_json("{ \"c1\":\"data\" }", "\$!parsed");
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+
+startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='{ "parsed": { "c1": "data" } }'
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/rscript_parse_time.sh b/tests/rscript_parse_time.sh
new file mode 100755
index 0000000..633f270
--- /dev/null
+++ b/tests/rscript_parse_time.sh
@@ -0,0 +1,122 @@
+#!/bin/bash
+# Added 2017-10-28 by Stephen Workman, released under ASL 2.0
+
+# Because this script tests functionality that depends on the current date,
+# we cannot use static values for the expected results. They have to be
+# calculated. Also, because we cannot depend on the GNU version of the
+# 'date' command on all of our test systems (think FreeBSD, and Solaris),
+# we need a method of converting given date/time strings to UNIX timestamps.
+# For that we use an external Python 2.x script to do the job.
+. ${srcdir:=.}/diag.sh init
+
+getts="$PYTHON $srcdir/rscript_parse_time_get-ts.py"
+
+# Run the Python script's self-tests
+$getts selftest
+
+if [[ $? -ne 0 ]]; then
+ printf "Failed own self-test(s)!\n"
+ error_exit 1
+fi
+
+# Since the RFC 3164 date/time format does not include a year, we need to
+# try to "guess" an appropriate one based on the incoming date and the
+# current date. So, we'll use a reasonable spread of RFC 3164 date/time
+# strings to ensure that we test as much of our year "guessing" as
+# possible. Since this uses the CURRENT DATE (as in, the date this)
+# script was invoked, we need to calculate our expected results to
+# compare them with the values returned by the parse_time() RainerScript
+# function.
+rfc3164_1="Oct 5 01:10:11"
+rfc3164_1_r=$($getts "$rfc3164_1")
+
+rfc3164_2="Jan 31 13:00:00"
+rfc3164_2_r=$($getts "$rfc3164_2")
+
+rfc3164_3="Feb 28 14:35:00"
+rfc3164_3_r=$($getts "$rfc3164_3")
+
+rfc3164_4="Mar 1 14:00:00"
+rfc3164_4_r=$($getts "$rfc3164_4")
+
+rfc3164_5="Apr 3 15:00:00"
+rfc3164_5_r=$($getts "$rfc3164_5")
+
+rfc3164_6="May 5 16:00:00"
+rfc3164_6_r=$($getts "$rfc3164_6")
+
+rfc3164_7="Jun 11 03:00:00"
+rfc3164_7_r=$($getts "$rfc3164_7")
+
+rfc3164_8="Jul 15 05:00:00"
+rfc3164_8_r=$($getts "$rfc3164_8")
+
+rfc3164_9="Aug 17 08:00:00"
+rfc3164_9_r=$($getts "$rfc3164_9")
+
+rfc3164_10="Sep 20 18:00:00"
+rfc3164_10_r=$($getts "$rfc3164_10")
+
+rfc3164_11="Nov 23 19:00:00"
+rfc3164_11_r=$($getts "$rfc3164_11")
+
+rfc3164_12="Dec 25 20:00:00"
+rfc3164_12_r=$($getts "$rfc3164_12")
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omstdout/.libs/omstdout")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# $DebugLevel 2
+
+# RFC 3164 Parse Tests (using fixed input values - see above)
+set $!datetime!rfc3164_1 = parse_time("'"$rfc3164_1"'");
+set $!datetime!rfc3164_2 = parse_time("'"$rfc3164_2"'");
+set $!datetime!rfc3164_3 = parse_time("'"$rfc3164_3"'");
+set $!datetime!rfc3164_4 = parse_time("'"$rfc3164_4"'");
+set $!datetime!rfc3164_5 = parse_time("'"$rfc3164_5"'");
+set $!datetime!rfc3164_6 = parse_time("'"$rfc3164_6"'");
+set $!datetime!rfc3164_7 = parse_time("'"$rfc3164_7"'");
+set $!datetime!rfc3164_8 = parse_time("'"$rfc3164_8"'");
+set $!datetime!rfc3164_9 = parse_time("'"$rfc3164_9"'");
+set $!datetime!rfc3164_10 = parse_time("'"$rfc3164_10"'");
+set $!datetime!rfc3164_11 = parse_time("'"$rfc3164_11"'");
+set $!datetime!rfc3164_12 = parse_time("'"$rfc3164_12"'");
+
+# RFC 3339 Parse Tests (these provide their own year)
+set $!datetime!rfc3339 = parse_time("2017-10-05T01:10:11Z");
+set $!datetime!rfc3339tz1 = parse_time("2017-10-05T01:10:11+04:00");
+set $!datetime!rfc3339tz2 = parse_time("2017-10-05T01:10:11+00:00");
+
+# Test invalid date strings, these should return 0
+set $!datetime!inval1 = parse_time("not a date/time");
+set $!datetime!inval2 = parse_time("2017-10-05T01:10:11");
+set $!datetime!inval3 = parse_time("2017-SOMETHING: 42");
+
+template(name="outfmt" type="string" string="%!datetime%\n")
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+local4.* :omstdout:;outfmt
+'
+
+startup
+tcpflood -m1 -y
+shutdown_when_empty
+wait_shutdown
+
+# Our fixed and calculated expected results
+export EXPECTED='{ "rfc3164_1": '"$rfc3164_1_r"', "rfc3164_2": '"$rfc3164_2_r"', "rfc3164_3": '"$rfc3164_3_r"', "rfc3164_4": '"$rfc3164_4_r"', "rfc3164_5": '"$rfc3164_5_r"', "rfc3164_6": '"$rfc3164_6_r"', "rfc3164_7": '"$rfc3164_7_r"', "rfc3164_8": '"$rfc3164_8_r"', "rfc3164_9": '"$rfc3164_9_r"', "rfc3164_10": '"$rfc3164_10_r"', "rfc3164_11": '"$rfc3164_11_r"', "rfc3164_12": '"$rfc3164_12_r"', "rfc3339": 1507165811, "rfc3339tz1": 1507151411, "rfc3339tz2": 1507165811, "inval1": 0, "inval2": 0, "inval3": 0 }'
+
+# FreeBSD's cmp does not support reading from STDIN
+cmp <(echo "$EXPECTED") $RSYSLOG_OUT_LOG
+
+if [[ $? -ne 0 ]]; then
+ printf "Invalid function output detected!\n"
+ printf "Expected: $EXPECTED\n"
+ printf "Got: "
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/rscript_parse_time_get-ts.py b/tests/rscript_parse_time_get-ts.py
new file mode 100644
index 0000000..f7e3787
--- /dev/null
+++ b/tests/rscript_parse_time_get-ts.py
@@ -0,0 +1,152 @@
+# call this via "python[3] script name"
+# Added 2017-11-05 by Stephen Workman, released under ASL 2.0
+
+#
+# Produces a UNIX timestamp representing the specified RFC 3164 date/time
+# string. Since this date/time format does not include a year, a simple
+# algorithm is used to "guess" an appropriate one and append it to the
+# date/time string to calculate a timestamp value.
+#
+# If the incoming date is within one month in the future (from now),
+# it is assumed that it's either for the current year, or the next
+# year (depending on whether it is December or not).
+# - For example:
+# * If today is December 13th 2017 and we get passed the date/time
+# string "Jan 4 01:00:00", we assume that it is for the next
+# year (2018).
+# * If today is October 5th 2017, and we get passed the date/time
+# string "Nov 5 01:10:11", we assume that it is for this year.
+# If the incoming date has a month "before" the current month, or does
+# not fall into the situation above, it's assumed it's from the past.
+# - For example:
+# * If today is July 10th 2017, and the incoming date is for
+# a time in April, the year is assumed to be 2017.
+# * If today is July 10th 2017, and the incoming date is for
+# a time in September, the year is assumed to be 2016.
+#
+
+import re
+import sys
+
+from datetime import datetime, timedelta
+
+err = 0
+
+# Make tests below a little easier to read.
+JAN = 1; FEB = 2; MAR = 3; APR = 4
+MAY = 5; JUN = 6; JUL = 7; AUG = 8
+SEP = 9; OCT = 10; NOV = 11; DEC = 12
+
+# Run the provided expression and compare its result with the
+# expected value. The function expects the expression to be
+# passed in as a string so it can be printed to the screen
+# as-is when there is an error.
+def do_test(expr, val):
+ global err
+
+ # Run the expression and record the result
+ result = eval(expr)
+
+ # Print a message identifying the failing "test"
+ if result != val:
+ print("Error: %s. Expected %4d, got %4d!" % (expr, val, result))
+ err += 1
+
+# Use a sliding 12-month window (offset by one month)
+# to determine the year that should be returned.
+# cy - Current Year
+# cm - Current Month
+# im - Incoming Month
+def estimate_year(cy, cm, im):
+ im += 12
+
+ if (im - cm) == 1:
+ if cm == 12 and im == 13:
+ return cy + 1
+
+ if (im - cm) > 13:
+ return cy - 1
+
+ return cy;
+
+# A quick and dirty unit test to validate that our
+# estimate_year() function is working as it should.
+def self_test():
+
+ # Where the incoming month is within one month
+ # in the future. Should be the NEXT year if
+ # the current date is in December, or the SAME
+ # year if it's not December.
+ do_test("estimate_year(2017, DEC, JAN)", 2018)
+ do_test("estimate_year(2017, NOV, DEC)", 2017)
+ do_test("estimate_year(2017, OCT, NOV)", 2017)
+ do_test("estimate_year(2017, SEP, OCT)", 2017)
+ do_test("estimate_year(2017, AUG, SEP)", 2017)
+
+ # These tests validate months that are MORE than
+ # one month in the future OR are before the current
+ # month. If, numerically, the month comes after the
+ # current month, it's assumed to be for the year
+ # PRIOR, otherwise it's assumed to be from THIS year.
+ do_test("estimate_year(2017, NOV, JAN)", 2017)
+ do_test("estimate_year(2017, NOV, FEB)", 2017)
+ do_test("estimate_year(2017, AUG, OCT)", 2016)
+ do_test("estimate_year(2017, AUG, MAR)", 2017)
+ do_test("estimate_year(2017, APR, JUL)", 2016)
+
+ do_test("estimate_year(2017, AUG, JAN)", 2017)
+ do_test("estimate_year(2017, APR, FEB)", 2017)
+
+ # Additional validations based on what was described
+ # above.
+ do_test("estimate_year(2017, JAN, DEC)", 2016)
+ do_test("estimate_year(2017, JAN, FEB)", 2017)
+ do_test("estimate_year(2017, JAN, MAR)", 2016)
+
+# Convert a datetime.timedelta object to a UNIX timestamp
+def get_total_seconds(dt):
+ # timedelta.total_seconds() wasn't added until
+ # Python 2.7, which CentOS 6 doesn't have.
+
+ if hasattr(timedelta, "total_seconds"):
+ return dt.total_seconds()
+ return dt.seconds + dt.days * 24 * 3600
+
+if __name__ == "__main__":
+ if len(sys.argv) != 2:
+ print("Invalid number of arguments!")
+ sys.exit(1)
+
+ if sys.argv[1] == "selftest":
+ self_test()
+
+ # Exit with non-zero if there were failures,
+ # zero otherwise.
+ sys.exit(err)
+
+ months = [None, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+
+ current_datetime = datetime.utcnow()
+
+ # The argument is expected to be an RFC 3164 timestamp
+ # such as "Oct 5 01:10:11".
+ incoming_datetime = sys.argv[1]
+
+ # Get the name of the month from the date/time string that was passed in
+ # and convert it to its ordinal number (1 for Jan, 10 for Oct, etc...)
+ incoming_month = re.search(r"^([^ ]+) ", incoming_datetime).group(1)
+ incoming_month = months.index(incoming_month)
+
+ # Assume a year for the date/time passed in based off of today's date.
+ estimated_year = estimate_year(
+ current_datetime.year,
+ current_datetime.month,
+ incoming_month
+ )
+
+ # Convert the date/time string (now with a year, e.g. "Oct 5 01:10:11 2017") to
+ # a python datetime object that we can use to calculate a UNIX timestamp
+ calculated_datetime = datetime.strptime("%s %d" % (incoming_datetime, estimated_year), "%b %d %H:%M:%S %Y")
+
+ # Convert the datetime object to a UNIX timestamp by subtracting it from the epoch
+ print(int( get_total_seconds(calculated_datetime - datetime(1970,1,1)) ))
diff --git a/tests/rscript_previous_action_suspended.sh b/tests/rscript_previous_action_suspended.sh
new file mode 100755
index 0000000..7bf1624
--- /dev/null
+++ b/tests/rscript_previous_action_suspended.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Added 2017-12-09 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omtesting/.libs/omtesting")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+ruleset(name="output_writer") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+
+:msg, contains, "msgnum:" {
+ :omtesting:fail 2 0
+ if previous_action_suspended() then
+ call output_writer
+}
+'
+
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+seq_check 1 9
+exit_test
diff --git a/tests/rscript_prifilt.sh b/tests/rscript_prifilt.sh
new file mode 100755
index 0000000..af546d0
--- /dev/null
+++ b/tests/rscript_prifilt.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# added 2012-09-20 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_prifilt.sh\]: testing rainerscript prifield\(\) function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="msg" field.delimiter="58" field.number="2")
+ constant(value="\n")
+}
+
+/* tcpflood uses local4.=debug, we use a bit more generic filter */
+if prifilt("local4.*") then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/rscript_privdropgroup.sh b/tests/rscript_privdropgroup.sh
new file mode 100755
index 0000000..62c44f0
--- /dev/null
+++ b/tests/rscript_privdropgroup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2021-09-23 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on Solaris."
+. $srcdir/privdrop_common.sh
+rsyslog_testbench_setup_testuser
+
+generate_conf
+add_conf '
+global(privdrop.group.keepsupplemental="on" privdrop.group.name="'${TESTBENCH_TESTUSER[groupname]}'")
+template(name="outfmt" type="list") {
+ property(name="msg" compressSpace="on")
+ constant(value="\n")
+}
+action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "groupid.*${TESTBENCH_TESTUSER[gid]}"
+exit_test
diff --git a/tests/rscript_privdropgroupid.sh b/tests/rscript_privdropgroupid.sh
new file mode 100755
index 0000000..b1eade2
--- /dev/null
+++ b/tests/rscript_privdropgroupid.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2021-09-23 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on Solaris."
+. $srcdir/privdrop_common.sh
+rsyslog_testbench_setup_testuser
+
+generate_conf
+add_conf '
+global(privdrop.group.keepsupplemental="on" privdrop.group.id="'${TESTBENCH_TESTUSER[gid]}'")
+template(name="outfmt" type="list") {
+ property(name="msg" compressSpace="on")
+ constant(value="\n")
+}
+action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "groupid.*${TESTBENCH_TESTUSER[gid]}"
+exit_test
diff --git a/tests/rscript_privdropuser.sh b/tests/rscript_privdropuser.sh
new file mode 100755
index 0000000..5a91479
--- /dev/null
+++ b/tests/rscript_privdropuser.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2021-09-23 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on Solaris."
+. $srcdir/privdrop_common.sh
+rsyslog_testbench_setup_testuser
+
+generate_conf
+add_conf '
+global(privdrop.user.name="'${TESTBENCH_TESTUSER[username]}'")
+template(name="outfmt" type="list") {
+ property(name="msg" compressSpace="on")
+ constant(value="\n")
+}
+action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "userid.*${TESTBENCH_TESTUSER[uid]}"
+exit_test
diff --git a/tests/rscript_privdropuserid.sh b/tests/rscript_privdropuserid.sh
new file mode 100755
index 0000000..3e66663
--- /dev/null
+++ b/tests/rscript_privdropuserid.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2021-09-23 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test currently does not work on Solaris."
+. $srcdir/privdrop_common.sh
+rsyslog_testbench_setup_testuser
+
+generate_conf
+add_conf '
+global(privdrop.user.id="'${TESTBENCH_TESTUSER[uid]}'")
+template(name="outfmt" type="list") {
+ property(name="msg" compressSpace="on")
+ constant(value="\n")
+}
+action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check --regex "userid.*${TESTBENCH_TESTUSER[uid]}"
+exit_test
diff --git a/tests/rscript_random.sh b/tests/rscript_random.sh
new file mode 100755
index 0000000..341fddb
--- /dev/null
+++ b/tests/rscript_random.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# added 2015-06-22 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_random.sh\]: test for random-number-generator script-function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$.random_no%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $.random_no = random(10);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 20
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+. $srcdir/diag.sh content-pattern-check "^[0-9]$"
+exit_test
diff --git a/tests/rscript_re_extract.sh b/tests/rscript_re_extract.sh
new file mode 100755
index 0000000..fcfb385
--- /dev/null
+++ b/tests/rscript_re_extract.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# added 2015-09-29 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_re_extract.sh\]: test re_extract rscript-fn
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="*Number is %$.number%*\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")'
+add_conf "
+set \$.number = re_extract(\$msg, '.* ([0-9]+)$', 0, 1, 'none');"
+add_conf '
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/date_time_msg
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "*Number is 19597*"
+exit_test
diff --git a/tests/rscript_re_extract_i.sh b/tests/rscript_re_extract_i.sh
new file mode 100755
index 0000000..fb45277
--- /dev/null
+++ b/tests/rscript_re_extract_i.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2015-09-29 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="msg is %$.test%\n")
+
+set $.test = re_extract_i($msg, "msg (.*)", 0, 1, "none");
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+injectmsg_literal "<167>Jan 16 16:57:54 172.20.245.8 TAG: MsG test1"
+injectmsg_literal "<167>Jan 16 16:57:54 172.20.245.8 TAG: MsG test2"
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "msg is test1"
+content_check "msg is test2"
+exit_test
diff --git a/tests/rscript_re_match-dbl_quotes.sh b/tests/rscript_re_match-dbl_quotes.sh
new file mode 100755
index 0000000..ebc7ae4
--- /dev/null
+++ b/tests/rscript_re_match-dbl_quotes.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Test that '$' in double-quoted string constants raise a meaningful
+# error message and do not cause rsyslog to segfault.
+# added 2019-12-30 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'") # order is important ...
+set $!test="test$" # ... as after this syntax error nothing is really taken up
+'
+startup
+shutdown_when_empty
+wait_shutdown
+content_check '$-sign in double quotes must be escaped'
+exit_test
diff --git a/tests/rscript_re_match.sh b/tests/rscript_re_match.sh
new file mode 100755
index 0000000..382ef02
--- /dev/null
+++ b/tests/rscript_re_match.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2015-09-29 by singh.janmejay
+# test re_match rscript-fn, using single quotes for the match
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="*Matched*\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+if (re_match($msg, '"'"'.* ([0-9]+)$'"'"')) then {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/date_time_msg
+shutdown_when_empty
+wait_shutdown
+content_check "*Matched*"
+exit_test
diff --git a/tests/rscript_re_match_i.sh b/tests/rscript_re_match_i.sh
new file mode 100755
index 0000000..f7b63fa
--- /dev/null
+++ b/tests/rscript_re_match_i.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+# added 2015-09-29 by singh.janmejay
+# test re_match rscript-fn, using single quotes for the match
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="*Matched*\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+if (re_match_i($msg, "RANDOM NUMBER")) then {
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/date_time_msg
+shutdown_when_empty
+wait_shutdown
+content_check "*Matched*"
+exit_test
diff --git a/tests/rscript_replace.sh b/tests/rscript_replace.sh
new file mode 100755
index 0000000..553ee80
--- /dev/null
+++ b/tests/rscript_replace.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# added 2014-10-31 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_replace.sh\]: test for replace script-function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$.replaced_msg%\n")
+
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="date_time" type="list") {
+ property(name="msg" regex.Expression="Thu .+ 2014" regex.Type="ERE" regex.Match="0")
+}
+
+set $.replaced_msg = replace("date time: " & exec_template("date_time"), "O" & "ct", replace("october", "o", "0"));
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/date_time_msg
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "date time: Thu 0ct0ber 30 13:20:18 IST 2014"
+exit_test
diff --git a/tests/rscript_replace_complex.sh b/tests/rscript_replace_complex.sh
new file mode 100755
index 0000000..ddc02e4
--- /dev/null
+++ b/tests/rscript_replace_complex.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# added 2014-10-31 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_replace_complex.sh\]: a more complex test for replace script-function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$.replaced_msg%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $.replaced_msg = replace($msg, "syslog", "rsyslog");
+set $.replaced_msg = replace($.replaced_msg, "hello", "hello_world");
+set $.replaced_msg = replace($.replaced_msg, "foo_bar_baz", "FBB");
+set $.replaced_msg = replace($.replaced_msg, "as_longer_this_string_as_more_probability_to_catch_the_bug", "ss");
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/complex_replace_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "try to replace rsyslog and syrsyslog with rrsyslog"
+content_check "try to replace hello_world in hello_worldlo and helhello_world with hello_world_world"
+content_check "try to FBB in FBB_quux and quux_FBB with FBB"
+content_check "in the end of msg; try to not lose as_longer_this_string_as_more_probability_to_catch_the_bu"
+exit_test
diff --git a/tests/rscript_ruleset_call.sh b/tests/rscript_ruleset_call.sh
new file mode 100755
index 0000000..fa25891
--- /dev/null
+++ b/tests/rscript_ruleset_call.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# added 2012-10-29 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_ruleset_call.sh\]: testing rainerscript ruleset\(\) and call statement
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="msg" field.delimiter="58" field.number="2")
+ constant(value="\n")
+}
+
+
+# we deliberately include continue/stop to make sure we have more than
+# one statement. This catches grammar errors
+ruleset(name="rs2") {
+ continue
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+ stop
+}
+
+# this time we make sure a single statement is properly supported
+ruleset(name="rs1") {
+ call rs2
+}
+
+if $msg contains "msgnum" then call rs1
+'
+startup
+injectmsg 0 5000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/rscript_ruleset_call_indirect-basic.sh b/tests/rscript_ruleset_call_indirect-basic.sh
new file mode 100755
index 0000000..ea9b21d
--- /dev/null
+++ b/tests/rscript_ruleset_call_indirect-basic.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# added 2016-12-11 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="msg" field.delimiter="58" field.number="2")
+ constant(value="\n")
+}
+
+ruleset(name="rs") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+
+if $msg contains "msgnum" then call_indirect "r" & "s";
+'
+startup
+injectmsg 0 100
+shutdown_when_empty
+wait_shutdown
+seq_check 0 99
+exit_test
diff --git a/tests/rscript_ruleset_call_indirect-invld.sh b/tests/rscript_ruleset_call_indirect-invld.sh
new file mode 100755
index 0000000..fcd959c
--- /dev/null
+++ b/tests/rscript_ruleset_call_indirect-invld.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# added 2016-12-11 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="msg" field.delimiter="58" field.number="2")
+ constant(value="\n")
+}
+
+ruleset(name="rs") {
+ action(type="omfile" file="./'"${RSYSLOG2_OUT_LOG}"'" template="outfmt")
+}
+
+if $msg contains "msgnum" then
+ call_indirect "does-not-exist";
+else
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+injectmsg 0 5
+shutdown_when_empty
+wait_shutdown
+grep "error.*does-not-exist" $RSYSLOG_OUT_LOG > /dev/null
+if [ $? -ne 0 ]; then
+ echo
+ echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi
+exit_test
diff --git a/tests/rscript_ruleset_call_indirect-var.sh b/tests/rscript_ruleset_call_indirect-var.sh
new file mode 100755
index 0000000..e219eba
--- /dev/null
+++ b/tests/rscript_ruleset_call_indirect-var.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# added 2016-12-11 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="msg" field.delimiter="58" field.number="2")
+ constant(value="\n")
+}
+
+ruleset(name="rs") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+
+set $.var = "rs";
+
+if $msg contains "msgnum" then call_indirect $.var;
+'
+startup
+injectmsg 0 100
+shutdown_when_empty
+wait_shutdown
+seq_check 0 99
+exit_test
diff --git a/tests/rscript_script_error.sh b/tests/rscript_script_error.sh
new file mode 100755
index 0000000..372e8d0
--- /dev/null
+++ b/tests/rscript_script_error.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Added 2017-12-09 by Rainer Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="string" string="%$!%\n")
+
+local4.* {
+ set $!valid!serial = parse_time("2017-10-05T01:10:11Z");
+ set $!valid!error = script_error();
+ set $!invalid!serial = parse_time("not a date/time");
+ set $!invalid!error = script_error();
+ set $!valid2!serial = parse_time("2017-10-05T01:10:11Z");
+ set $!valid2!error = script_error();
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+
+startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+
+# Our fixed and calculated expected results
+export EXPECTED='{ "valid": { "serial": 1507165811, "error": 0 }, "invalid": { "serial": 0, "error": 1 }, "valid2": { "serial": 1507165811, "error": 0 } }'
+cmp_exact $RSYSLOG_OUT_LOG
+
+exit_test
diff --git a/tests/rscript_set_memleak-vg.sh b/tests/rscript_set_memleak-vg.sh
new file mode 100755
index 0000000..bc4e0bc
--- /dev/null
+++ b/tests/rscript_set_memleak-vg.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# A test that checks for memory leaks
+# created based on real world case:
+# https://github.com/rsyslog/rsyslog/issues/1376
+# Copyright 2017-01-24 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+generate_conf
+add_conf '
+template(name="json" type="string" string="%$!%\n")
+template(name="ts" type="string" string="%timestamp:::date-rfc3339%")
+ruleset(name="rcvr" queue.type="LinkedList"
+ queue.timeoutShutdown="'$RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT'") {
+ set $.index="unknown";
+ set $.type="unknown";
+ set $.interval=$$now & ":" & $$hour;
+ set $!host_forwarded=$hostname;
+ set $!host_received=$$myhostname;
+ set $!time_received=$timegenerated;
+ set $!@timestamp=exec_template("ts");
+ action( type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="json"
+ )
+}'
+startup_vg
+injectmsg
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+# note: we check only the valgrind result, we are not really interested
+# in the output data (non-standard format in any way...)
+exit_test
diff --git a/tests/rscript_set_modify.sh b/tests/rscript_set_modify.sh
new file mode 100755
index 0000000..ea7099c
--- /dev/null
+++ b/tests/rscript_set_modify.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# Check if a set statement can correctly be reset to a different value
+# Copyright 2014-11-24 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_set_modify.sh\]: testing set twice
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 1);
+ set $!usr!msgnum = field($msg, 58, 2);
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 100
+shutdown_when_empty
+wait_shutdown
+seq_check 0 99
+exit_test
diff --git a/tests/rscript_set_unset_invalid_var.sh b/tests/rscript_set_unset_invalid_var.sh
new file mode 100755
index 0000000..a428be2
--- /dev/null
+++ b/tests/rscript_set_unset_invalid_var.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Check that invalid variable names are detected.
+# Copyright 2017-01-24 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="json" type="string" string="%$!%\n")
+ruleset(name="rcvr" queue.type="LinkedList") {
+ set $@timestamp="test";
+ unset $@timestamp2;
+ action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)
+}
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+
+'
+startup
+injectmsg 0 10
+shutdown_when_empty
+wait_shutdown
+
+grep "@timestamp" $RSYSLOG_OUT_LOG > /dev/null
+if [ ! $? -eq 0 ]; then
+ echo "expected error message on \"@timestamp\" not found, output is:"
+ echo "------------------------------------------------------------"
+ cat $RSYSLOG_OUT_LOG
+ echo "------------------------------------------------------------"
+ error_exit 1
+fi;
+
+grep "@timestamp2" $RSYSLOG_OUT_LOG > /dev/null
+if [ ! $? -eq 0 ]; then
+ echo "expected error message on \"@timestamp2\" not found, output is:"
+ echo "------------------------------------------------------------"
+ cat $RSYSLOG_OUT_LOG
+ echo "------------------------------------------------------------"
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/rscript_stop.sh b/tests/rscript_stop.sh
new file mode 100755
index 0000000..12729d4
--- /dev/null
+++ b/tests/rscript_stop.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2012-09-20 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_stop.sh\]: testing rainerscript STOP statement
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ if cnum($!usr!msgnum) >= 5000 then
+ stop
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 8000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/rscript_stop2.sh b/tests/rscript_stop2.sh
new file mode 100755
index 0000000..1390b03
--- /dev/null
+++ b/tests/rscript_stop2.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# added 2012-09-20 by rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_stop2.sh\]: testing rainerscript STOP statement, alternate method
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if not ($msg contains "msgnum") then
+ stop
+
+set $!usr!msgnum = field($msg, 58, 2);
+if cnum($!usr!msgnum) >= 5000 then
+ stop
+/* We could use yet another method, but we like to have the action statement
+ * without a filter in rsyslog.conf top level hierarchy - so this test, as
+ * a side-effect, also tests this ability.
+ */
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+injectmsg 0 8000
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+seq_check 0 4999
+exit_test
diff --git a/tests/rscript_str2num_negative.sh b/tests/rscript_str2num_negative.sh
new file mode 100755
index 0000000..b76ddf9
--- /dev/null
+++ b/tests/rscript_str2num_negative.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# add 2017-02-09 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $.n = "-1";
+set $!ip!v1 = 1 + $.n;
+
+template(name="outfmt" type="string" string="%!ip%\n")
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo '{ "v1": 0 }' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid function output detected, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+exit_test
diff --git a/tests/rscript_substring.sh b/tests/rscript_substring.sh
new file mode 100755
index 0000000..0767cce
--- /dev/null
+++ b/tests/rscript_substring.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2017-12-10 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $!str!var1 = substring("", 0, 0);
+set $!str!var2 = substring("test", 0, 4);
+set $!str!var3 = substring("test", 1, 2);
+set $!str!var4 = substring("test", 4, 2);
+set $!str!var5 = substring("test", 0, 5);
+set $!str!var6 = substring("test", 0, 6);
+set $!str!var7 = substring("test", 3, 4);
+set $!str!var8 = substring("test", 1, 0);
+
+template(name="outfmt" type="string" string="%!str%\n")
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m1 -y
+shutdown_when_empty
+wait_shutdown
+echo '{ "var1": "", "var2": "test", "var3": "es", "var4": "", "var5": "test", "var6": "test", "var7": "t", "var8": "" }' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid function output detected, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+exit_test
+
diff --git a/tests/rscript_trim-vg.sh b/tests/rscript_trim-vg.sh
new file mode 100755
index 0000000..d186a95
--- /dev/null
+++ b/tests/rscript_trim-vg.sh
@@ -0,0 +1,89 @@
+#!/bin/bash
+# add 2017-08-14 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $!str!l1 = ltrim("");
+set $!str!l2 = ltrim("test");
+set $!str!l3 = ltrim(" test");
+set $!str!l4 = ltrim("test ");
+set $!str!l5 = ltrim(" test ");
+set $!str!l6 = ltrim(" test");
+set $!str!l7 = ltrim("test ");
+set $!str!l8 = ltrim(" ");
+set $!str!l9 = ltrim("te st");
+set $!str!l10 = ltrim(" te st");
+set $!str!l11 = ltrim(" a");
+set $!str!l12 = ltrim("a ");
+
+set $!str!r1 = rtrim("");
+set $!str!r2 = rtrim("test");
+set $!str!r3 = rtrim(" test");
+set $!str!r4 = rtrim("test ");
+set $!str!r5 = rtrim(" test ");
+set $!str!r6 = rtrim(" test");
+set $!str!r7 = rtrim("test ");
+set $!str!r8 = rtrim(" ");
+set $!str!r9 = rtrim("te st");
+set $!str!r10 = rtrim("te st ");
+set $!str!r11 = rtrim(" a");
+set $!str!r12 = rtrim("a ");
+
+
+set $!str!b1 = ltrim(" ");
+set $!str!b1 = rtrim($!str!b1);
+
+set $!str!b2 = ltrim(" test ");
+set $!str!b2 = rtrim($!str!b2);
+
+set $!str!b3 = ltrim(" test ");
+set $!str!b3 = rtrim($!str!b3);
+
+set $!str!b4 = ltrim("te st");
+set $!str!b4 = rtrim($!str!b4);
+
+set $!str!b5 = rtrim(" ");
+set $!str!b5 = ltrim($!str!b5);
+
+set $!str!b6 = rtrim(" test ");
+set $!str!b6 = ltrim($!str!b6);
+
+set $!str!b7 = rtrim(" test ");
+set $!str!b7 = ltrim($!str!b7);
+
+set $!str!b8 = rtrim("te st");
+set $!str!b8 = ltrim($!str!b8);
+
+set $!str!b9 = rtrim(ltrim("test"));
+set $!str!b10 = rtrim(ltrim("te st"));
+set $!str!b11 = rtrim(ltrim(" test"));
+set $!str!b12 = rtrim(ltrim("test "));
+set $!str!b13 = rtrim(ltrim(" test "));
+set $!str!b14 = rtrim(ltrim(" te st "));
+
+set $!str!b15 = ltrim(rtrim("test"));
+set $!str!b16 = ltrim(rtrim("te st"));
+set $!str!b17 = ltrim(rtrim(" test"));
+set $!str!b18 = ltrim(rtrim("test "));
+set $!str!b19 = ltrim(rtrim(" test "));
+set $!str!b20 = ltrim(rtrim(" te st "));
+
+template(name="outfmt" type="string" string="%!str%\n")
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+tcpflood -m1 -y
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+echo '{ "l1": "", "l2": "test", "l3": "test", "l4": "test ", "l5": "test ", "l6": "test", "l7": "test ", "l8": "", "l9": "te st", "l10": "te st", "l11": "a", "l12": "a ", "r1": "", "r2": "test", "r3": " test", "r4": "test", "r5": " test", "r6": " test", "r7": "test", "r8": "", "r9": "te st", "r10": "te st", "r11": " a", "r12": "a", "b1": "", "b2": "test", "b3": "test", "b4": "te st", "b5": "", "b6": "test", "b7": "test", "b8": "te st", "b9": "test", "b10": "te st", "b11": "test", "b12": "test", "b13": "test", "b14": "te st", "b15": "test", "b16": "te st", "b17": "test", "b18": "test", "b19": "test", "b20": "te st" }' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid function output detected, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+exit_test
+
diff --git a/tests/rscript_trim.sh b/tests/rscript_trim.sh
new file mode 100755
index 0000000..a561102
--- /dev/null
+++ b/tests/rscript_trim.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+# add 2017-08-14 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $!str!l1 = ltrim("");
+set $!str!l2 = ltrim("test");
+set $!str!l3 = ltrim(" test");
+set $!str!l4 = ltrim("test ");
+set $!str!l5 = ltrim(" test ");
+set $!str!l6 = ltrim(" test");
+set $!str!l7 = ltrim("test ");
+set $!str!l8 = ltrim(" ");
+set $!str!l9 = ltrim("te st");
+set $!str!l10 = ltrim(" te st");
+set $!str!l11 = ltrim(" a");
+set $!str!l12 = ltrim("a ");
+
+set $!str!r1 = rtrim("");
+set $!str!r2 = rtrim("test");
+set $!str!r3 = rtrim(" test");
+set $!str!r4 = rtrim("test ");
+set $!str!r5 = rtrim(" test ");
+set $!str!r6 = rtrim(" test");
+set $!str!r7 = rtrim("test ");
+set $!str!r8 = rtrim(" ");
+set $!str!r9 = rtrim("te st");
+set $!str!r10 = rtrim("te st ");
+set $!str!r11 = rtrim(" a");
+set $!str!r12 = rtrim("a ");
+
+
+set $!str!b1 = ltrim(" ");
+set $!str!b1 = rtrim($!str!b1);
+
+set $!str!b2 = ltrim(" test ");
+set $!str!b2 = rtrim($!str!b2);
+
+set $!str!b3 = ltrim(" test ");
+set $!str!b3 = rtrim($!str!b3);
+
+set $!str!b4 = ltrim("te st");
+set $!str!b4 = rtrim($!str!b4);
+
+set $!str!b5 = rtrim(" ");
+set $!str!b5 = ltrim($!str!b5);
+
+set $!str!b6 = rtrim(" test ");
+set $!str!b6 = ltrim($!str!b6);
+
+set $!str!b7 = rtrim(" test ");
+set $!str!b7 = ltrim($!str!b7);
+
+set $!str!b8 = rtrim("te st");
+set $!str!b8 = ltrim($!str!b8);
+
+set $!str!b9 = rtrim(ltrim("test"));
+set $!str!b10 = rtrim(ltrim("te st"));
+set $!str!b11 = rtrim(ltrim(" test"));
+set $!str!b12 = rtrim(ltrim("test "));
+set $!str!b13 = rtrim(ltrim(" test "));
+set $!str!b14 = rtrim(ltrim(" te st "));
+
+set $!str!b15 = ltrim(rtrim("test"));
+set $!str!b16 = ltrim(rtrim("te st"));
+set $!str!b17 = ltrim(rtrim(" test"));
+set $!str!b18 = ltrim(rtrim("test "));
+set $!str!b19 = ltrim(rtrim(" test "));
+set $!str!b20 = ltrim(rtrim(" te st "));
+
+template(name="outfmt" type="string" string="%!str%\n")
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m1 -y
+shutdown_when_empty
+wait_shutdown
+echo '{ "l1": "", "l2": "test", "l3": "test", "l4": "test ", "l5": "test ", "l6": "test", "l7": "test ", "l8": "", "l9": "te st", "l10": "te st", "l11": "a", "l12": "a ", "r1": "", "r2": "test", "r3": " test", "r4": "test", "r5": " test", "r6": " test", "r7": "test", "r8": "", "r9": "te st", "r10": "te st", "r11": " a", "r12": "a", "b1": "", "b2": "test", "b3": "test", "b4": "te st", "b5": "", "b6": "test", "b7": "test", "b8": "te st", "b9": "test", "b10": "te st", "b11": "test", "b12": "test", "b13": "test", "b14": "te st", "b15": "test", "b16": "te st", "b17": "test", "b18": "test", "b19": "test", "b20": "te st" }' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid function output detected, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+exit_test
+
diff --git a/tests/rscript_unaffected_reset.sh b/tests/rscript_unaffected_reset.sh
new file mode 100755
index 0000000..5d33182
--- /dev/null
+++ b/tests/rscript_unaffected_reset.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Check if a set statement to the same subtree does not reset
+# other variables in that same subtree.
+# Copyright 2014-11-24 by Rainer Gerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_unaffected_reset.sh\]: testing set/reset
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="$!usr!msgnum")
+ constant(value="\n")
+}
+
+if $msg contains "msgnum" then {
+ set $!usr!msgnum = field($msg, 58, 2);
+ set $!usr!msgnum_reset = "dummy";
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+}
+'
+startup
+injectmsg 0 100
+shutdown_when_empty
+wait_shutdown
+seq_check 0 99
+exit_test
diff --git a/tests/rscript_unflatten_arg1_unsuitable-vg.sh b/tests/rscript_unflatten_arg1_unsuitable-vg.sh
new file mode 100755
index 0000000..527e4d3
--- /dev/null
+++ b/tests/rscript_unflatten_arg1_unsuitable-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/rscript_unflatten_arg1_unsuitable.sh
diff --git a/tests/rscript_unflatten_arg1_unsuitable.sh b/tests/rscript_unflatten_arg1_unsuitable.sh
new file mode 100755
index 0000000..9220134
--- /dev/null
+++ b/tests/rscript_unflatten_arg1_unsuitable.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# added 2021-03-09 by Julien Thomas, released under ASL 2.0
+
+source "${srcdir:=.}/diag.sh" init
+#export RSYSLOG_DEBUG="debug nostdout"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug"
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmunflatten/.libs/fmunflatten")
+input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n")
+
+if (not($msg contains "msgnum:")) then
+ stop
+
+set $.unflatten = unflatten($!, ".");
+set $.ret = script_error();
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1
+wait_file_lines "$RSYSLOG_OUT_LOG" 1 60
+shutdown_when_empty
+wait_shutdown
+
+EXPECTED=' msgnum:00000000: 1 0'
+cmp_exact "$RSYSLOG_OUT_LOG"
+exit_test
diff --git a/tests/rscript_unflatten_arg2_invalid-vg.sh b/tests/rscript_unflatten_arg2_invalid-vg.sh
new file mode 100755
index 0000000..68f0003
--- /dev/null
+++ b/tests/rscript_unflatten_arg2_invalid-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/rscript_unflatten_arg2_invalid.sh
diff --git a/tests/rscript_unflatten_arg2_invalid.sh b/tests/rscript_unflatten_arg2_invalid.sh
new file mode 100755
index 0000000..8ab6c4d
--- /dev/null
+++ b/tests/rscript_unflatten_arg2_invalid.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# added 2021-03-09 by Julien Thomas, released under ASL 2.0
+
+source "${srcdir:=.}/diag.sh" init
+#export RSYSLOG_DEBUG="debug nostdout"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug"
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmunflatten/.libs/fmunflatten")
+input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n")
+
+if (not($msg contains "msgnum:")) then
+ stop
+
+set $!a.b.c = "foobar";
+set $.unflatten = unflatten($!, "too many chars");
+set $.ret = script_error();
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1
+wait_file_lines "$RSYSLOG_OUT_LOG" 1 60
+shutdown_when_empty
+wait_shutdown
+
+EXPECTED=' msgnum:00000000: 1 0'
+cmp_exact "$RSYSLOG_OUT_LOG"
+exit_test
diff --git a/tests/rscript_unflatten_conflict1-vg.sh b/tests/rscript_unflatten_conflict1-vg.sh
new file mode 100755
index 0000000..c02399d
--- /dev/null
+++ b/tests/rscript_unflatten_conflict1-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/rscript_unflatten_conflict1.sh
diff --git a/tests/rscript_unflatten_conflict1.sh b/tests/rscript_unflatten_conflict1.sh
new file mode 100755
index 0000000..27040e2
--- /dev/null
+++ b/tests/rscript_unflatten_conflict1.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# added 2021-03-09 by Julien Thomas, released under ASL 2.0
+
+source "${srcdir:=.}/diag.sh" init
+export RSYSLOG_DEBUG="debug nostdout"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug"
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmunflatten/.libs/fmunflatten")
+input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n")
+
+if (not($msg contains "msgnum:")) then
+ stop
+
+set $!a!b = "foo";
+set $!a.b.c = "bar";
+set $.unflatten = unflatten($!, ".");
+set $.ret = script_error();
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1
+wait_file_lines "$RSYSLOG_OUT_LOG" 1 60
+shutdown_when_empty
+wait_shutdown
+
+# this test may need changes to produce a more deterministic
+# output by sorting keys
+EXPECTED=' msgnum:00000000: 0 { "a": { "b": { "c": "bar" } } }'
+cmp_exact "$RSYSLOG_OUT_LOG"
+
+EXPECTED='fmunflatten.c: warning: while processing flat key "a.b.c" at depth #1 (intermediate node), overriding existing value of type string by an object'
+if ! grep -F "$EXPECTED" "$RSYSLOG_DEBUGLOG"; then
+ echo "GREP FAILED"
+ echo " => FILE: $RSYSLOG_DEBUGLOG"
+ echo " => EXPECTED: $EXPECTED"
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/rscript_unflatten_conflict2-vg.sh b/tests/rscript_unflatten_conflict2-vg.sh
new file mode 100755
index 0000000..aca7a98
--- /dev/null
+++ b/tests/rscript_unflatten_conflict2-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/rscript_unflatten_conflict2.sh
diff --git a/tests/rscript_unflatten_conflict2.sh b/tests/rscript_unflatten_conflict2.sh
new file mode 100755
index 0000000..22ec6e0
--- /dev/null
+++ b/tests/rscript_unflatten_conflict2.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# added 2021-03-09 by Julien Thomas, released under ASL 2.0
+
+source "${srcdir:=.}/diag.sh" init
+export RSYSLOG_DEBUG="debug nostdout"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug"
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmunflatten/.libs/fmunflatten")
+input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n")
+
+if (not($msg contains "msgnum:")) then
+ stop
+
+set $.x!a = 21;
+set $!a!b = "foo";
+set $!a.b = $.x;
+set $.unflatten = unflatten($!, ".");
+set $.ret = script_error();
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1
+wait_file_lines "$RSYSLOG_OUT_LOG" 1 60
+shutdown_when_empty
+wait_shutdown
+
+# this test may need changes to produce a more deterministic
+# output by sorting keys
+EXPECTED=' msgnum:00000000: 0 { "a": { "b": { "a": 21 } } }'
+cmp_exact "$RSYSLOG_OUT_LOG"
+
+EXPECTED='fmunflatten.c: warning: while processing flat key "a.b" at depth #1 (final node), overriding existing value of type string by an object'
+if ! grep -F "$EXPECTED" "$RSYSLOG_DEBUGLOG"; then
+ echo "GREP FAILED"
+ echo " => FILE: $RSYSLOG_DEBUGLOG"
+ echo " => EXPECTED: $EXPECTED"
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/rscript_unflatten_conflict3-vg.sh b/tests/rscript_unflatten_conflict3-vg.sh
new file mode 100755
index 0000000..ee4404f
--- /dev/null
+++ b/tests/rscript_unflatten_conflict3-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/rscript_unflatten_conflict3.sh
diff --git a/tests/rscript_unflatten_conflict3.sh b/tests/rscript_unflatten_conflict3.sh
new file mode 100755
index 0000000..07a0485
--- /dev/null
+++ b/tests/rscript_unflatten_conflict3.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# added 2021-03-09 by Julien Thomas, released under ASL 2.0
+
+source "${srcdir:=.}/diag.sh" init
+export RSYSLOG_DEBUG="debug nostdout"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug"
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmunflatten/.libs/fmunflatten")
+input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n")
+
+if (not($msg contains "msgnum:")) then
+ stop
+
+set $!a!b = "foo";
+set $!a.b = "bar";
+set $.unflatten = unflatten($!, ".");
+set $.ret = script_error();
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1
+wait_file_lines "$RSYSLOG_OUT_LOG" 1 60
+shutdown_when_empty
+wait_shutdown
+
+# this test may need changes to produce a more deterministic
+# output by sorting keys
+EXPECTED=' msgnum:00000000: 0 { "a": { "b": "bar" } }'
+cmp_exact "$RSYSLOG_OUT_LOG"
+
+EXPECTED='fmunflatten.c: warning: while processing flat key "a.b" at depth #1 (final node), overriding existing value'
+if ! grep -F "$EXPECTED" "$RSYSLOG_DEBUGLOG"; then
+ echo "GREP FAILED"
+ echo " => FILE: $RSYSLOG_DEBUGLOG"
+ echo " => EXPECTED: $EXPECTED"
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/rscript_unflatten_key_truncated-vg.sh b/tests/rscript_unflatten_key_truncated-vg.sh
new file mode 100755
index 0000000..a7d7684
--- /dev/null
+++ b/tests/rscript_unflatten_key_truncated-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/rscript_unflatten_key_truncated.sh
diff --git a/tests/rscript_unflatten_key_truncated.sh b/tests/rscript_unflatten_key_truncated.sh
new file mode 100755
index 0000000..5dd3985
--- /dev/null
+++ b/tests/rscript_unflatten_key_truncated.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# added 2021-03-09 by Julien Thomas, released under ASL 2.0
+
+source "${srcdir:=.}/diag.sh" init
+export RSYSLOG_DEBUG="debug nostdout"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug"
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmunflatten/.libs/fmunflatten")
+input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n")
+
+if (not($msg contains "msgnum:")) then
+ stop
+
+set $!a.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb255ccccc.d = "bar";
+set $.unflatten = unflatten($!, ".");
+set $.ret = script_error();
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1
+wait_file_lines "$RSYSLOG_OUT_LOG" 1 60
+shutdown_when_empty
+wait_shutdown
+
+# this test may need changes to produce a more deterministic
+# output by sorting keys
+EXPECTED=' msgnum:00000000: 0 { "a": { "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb255": { "d": "bar" } } }'
+cmp_exact "$RSYSLOG_OUT_LOG"
+
+EXPECTED='fmunflatten.c: warning: flat key "a.bbbbbbbbbbbbbbbbbb..." truncated at depth #1, buffer too small (max 256)'
+if ! grep -F "$EXPECTED" "$RSYSLOG_DEBUGLOG"; then
+ echo "GREP FAILED"
+ echo " => FILE: $RSYSLOG_DEBUGLOG"
+ echo " => EXPECTED: $EXPECTED"
+ error_exit 1
+fi
+
+exit_test
diff --git a/tests/rscript_unflatten_non_object-vg.sh b/tests/rscript_unflatten_non_object-vg.sh
new file mode 100755
index 0000000..aa18e1d
--- /dev/null
+++ b/tests/rscript_unflatten_non_object-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/rscript_unflatten_non_object.sh
diff --git a/tests/rscript_unflatten_non_object.sh b/tests/rscript_unflatten_non_object.sh
new file mode 100755
index 0000000..cfdc052
--- /dev/null
+++ b/tests/rscript_unflatten_non_object.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# added 2021-03-09 by Julien Thomas, released under ASL 2.0
+
+source "${srcdir:=.}/diag.sh" init
+#export RSYSLOG_DEBUG="debug nostdout"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug"
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmunflatten/.libs/fmunflatten")
+input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n")
+
+if (not($msg contains "msgnum:")) then
+ stop
+
+set $/cpt = $/cpt + 1;
+if ($/cpt == 1) then
+ set $! = "string";
+else
+ set $! = 42;
+
+set $.unflatten = unflatten($!, ".");
+set $.ret = script_error();
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 2
+wait_file_lines "$RSYSLOG_OUT_LOG" 2 60
+shutdown_when_empty
+wait_shutdown
+
+EXPECTED=' msgnum:00000000: 0 string
+ msgnum:00000001: 0 42'
+cmp_exact "$RSYSLOG_OUT_LOG"
+exit_test
diff --git a/tests/rscript_unflatten_object-vg.sh b/tests/rscript_unflatten_object-vg.sh
new file mode 100755
index 0000000..acda4bb
--- /dev/null
+++ b/tests/rscript_unflatten_object-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/rscript_unflatten_object.sh
diff --git a/tests/rscript_unflatten_object.sh b/tests/rscript_unflatten_object.sh
new file mode 100755
index 0000000..084fc94
--- /dev/null
+++ b/tests/rscript_unflatten_object.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# added 2020-08-16 by Julien Thomas, released under ASL 2.0
+
+source "${srcdir:=.}/diag.sh" init
+#export RSYSLOG_DEBUG="debug nostdout"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug"
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmunflatten/.libs/fmunflatten")
+input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n")
+
+if (not($msg contains "msgnum:")) then
+ stop
+
+set $!source.ip = "1.2.3.4";
+set $!source.bytes = 3258;
+set $!source.geo.country_iso_code = "FR";
+set $!destination.ip = "4.3.2.1";
+
+set $.unflatten = unflatten($!, ".");
+set $.ret = script_error();
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 3
+wait_file_lines "$RSYSLOG_OUT_LOG" 3 60
+shutdown_when_empty
+wait_shutdown
+
+# this test may need changes to produce a more deterministic
+# output by sorting keys
+EXPECTED=' msgnum:00000000: 0 { "source": { "ip": "1.2.3.4", "bytes": 3258, "geo": { "country_iso_code": "FR" } }, "destination": { "ip": "4.3.2.1" } }
+ msgnum:00000001: 0 { "source": { "ip": "1.2.3.4", "bytes": 3258, "geo": { "country_iso_code": "FR" } }, "destination": { "ip": "4.3.2.1" } }
+ msgnum:00000002: 0 { "source": { "ip": "1.2.3.4", "bytes": 3258, "geo": { "country_iso_code": "FR" } }, "destination": { "ip": "4.3.2.1" } }'
+cmp_exact "$RSYSLOG_OUT_LOG"
+exit_test
diff --git a/tests/rscript_unflatten_object_exclamation-vg.sh b/tests/rscript_unflatten_object_exclamation-vg.sh
new file mode 100755
index 0000000..292be2d
--- /dev/null
+++ b/tests/rscript_unflatten_object_exclamation-vg.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/rscript_unflatten_object_exclamation.sh
diff --git a/tests/rscript_unflatten_object_exclamation.sh b/tests/rscript_unflatten_object_exclamation.sh
new file mode 100755
index 0000000..d9e84cd
--- /dev/null
+++ b/tests/rscript_unflatten_object_exclamation.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# added 2020-08-16 by Julien Thomas, released under ASL 2.0
+
+source "${srcdir:=.}/diag.sh" init
+#export RSYSLOG_DEBUG="debug nostdout"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug"
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../contrib/fmunflatten/.libs/fmunflatten")
+input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port")
+template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n")
+
+if (not($msg contains "msgnum:")) then
+ stop
+
+set $.ret = parse_json("{\"source!ip\":\"1.2.3.4\",\"source!port\":53}", "\$!");
+set $.unflatten = unflatten($!, "!");
+set $.ret = script_error();
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 2
+wait_file_lines "$RSYSLOG_OUT_LOG" 2 60
+shutdown_when_empty
+wait_shutdown
+
+# this test may need changes to produce a more deterministic
+# output by sorting keys
+EXPECTED=' msgnum:00000000: 0 { "source": { "ip": "1.2.3.4", "port": 53 } }
+ msgnum:00000001: 0 { "source": { "ip": "1.2.3.4", "port": 53 } }'
+cmp_exact "$RSYSLOG_OUT_LOG"
+exit_test
diff --git a/tests/rscript_wrap2.sh b/tests/rscript_wrap2.sh
new file mode 100755
index 0000000..08cb067
--- /dev/null
+++ b/tests/rscript_wrap2.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# added 2014-11-03 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_wrap2.sh\]: a test for wrap\(2\) script-function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$.replaced_msg%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $.replaced_msg = wrap("foo says" & $msg, "*" & "*");
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/date_time_msg
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "**foo says at Thu Oct 30 13:20:18 IST 2014 random number is 19597**"
+exit_test
diff --git a/tests/rscript_wrap3.sh b/tests/rscript_wrap3.sh
new file mode 100755
index 0000000..69d20c7
--- /dev/null
+++ b/tests/rscript_wrap3.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# added 2014-11-03 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[rscript_wrap3.sh\]: a test for wrap\(3\) script-function
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$.replaced_msg%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+set $.replaced_msg = wrap("foo says" & $msg, "bc" & "def" & "bc", "ES" & "C");
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/wrap3_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "bcdefbcfoo says a abcESCdefb has ESCbcdefbc"
+exit_test
diff --git a/tests/rsf_getenv.sh b/tests/rsf_getenv.sh
new file mode 100755
index 0000000..a981f20
--- /dev/null
+++ b/tests/rsf_getenv.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# Test for the getenv() rainerscript function
+# this is a quick test, but it guarantees 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:
+export NUMMESSAGES=10000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+export MSGNUM="msgnum:"
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+if $msg contains getenv("MSGNUM") then ?dynfile;outfmt
+'
+startup
+injectmsg
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/ruleset-direct-queue.sh b/tests/ruleset-direct-queue.sh
new file mode 100755
index 0000000..f0b0e95
--- /dev/null
+++ b/tests/ruleset-direct-queue.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# check that ruleset is called synchronously when queue.type="direct" is
+# specified in ruleset.
+# added 2021-09-17 by rgerhards. Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+export STATSFILE="$RSYSLOG_DYNNAME.stats"
+add_conf '
+template(name="outfmt" type="string" string="%msg%,%$.msg%\n")
+
+ruleset(name="rs1" queue.type="direct") {
+ set $.msg = "TEST";
+}
+
+
+if $msg contains "msgnum:" then {
+ set $.msg = $msg;
+ call rs1
+ action(type="omfile" name="main-action" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+}
+'
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+content_check "msgnum:00000000:,TEST"
+exit_test
diff --git a/tests/rulesetmultiqueue-v6.sh b/tests/rulesetmultiqueue-v6.sh
new file mode 100755
index 0000000..157b8a4
--- /dev/null
+++ b/tests/rulesetmultiqueue-v6.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+# Test for disk-only queue mode with v6+ config
+# This tests defines three rulesets, each one with its own queue. Then, it
+# sends data to them and checks the outcome. Note that we do need to
+# use some custom code as the test driver framework does not (yet?)
+# support multi-output-file operations.
+# added 2013-11-14 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test does not work on Solaris. The overall queue
+size check in imdiag requires atomics or mutexes on this platform, which we
+do not use for performance reasons."
+export NUMMESSAGES=60000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+
+# general definition
+$template outfmt,"%msg:F,58:2%\n"
+
+# create the individual rulesets
+$template dynfile1,"'$RSYSLOG_OUT_LOG'1.log" # trick to use relative path names!
+ruleset(name="file1" queue.type="linkedList") {
+ :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+ :msg, contains, "msgnum:" ?dynfile1;outfmt
+}
+
+$template dynfile2,"'$RSYSLOG_OUT_LOG'2.log" # trick to use relative path names!
+ruleset(name="file2" queue.type="linkedList") {
+ :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+ :msg, contains, "msgnum:" ?dynfile2;outfmt
+}
+
+$template dynfile3,"'$RSYSLOG_OUT_LOG'3.log" # trick to use relative path names!
+ruleset(name="file3" queue.type="linkedList") {
+ :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+ :msg, contains, "msgnum:" ?dynfile3;outfmt
+}
+
+# start listeners and bind them to rulesets
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="file1")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port2" ruleset="file2")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port3" ruleset="file3")
+'
+startup
+assign_tcpflood_port2 "$RSYSLOG_DYNNAME.tcpflood_port2"
+assign_rs_port "$RSYSLOG_DYNNAME.tcpflood_port3"
+# now fill the three files (a bit sequentially, but they should
+# still get their share of concurrency - to increase the chance
+# we use three connections per set).
+tcpflood -c3 -p$TCPFLOOD_PORT -m20000 -i0
+tcpflood -c3 -p$TCPFLOOD_PORT2 -m20000 -i20000
+tcpflood -c3 -p$RS_PORT -m20000 -i40000
+shutdown_when_empty
+wait_shutdown
+# now consolidate all logs into a single one so that we can use the
+seq_check # do a check on the count file - doesn't hurt as we need it anyhow
+# regular check logic
+cat ${RSYSLOG_OUT_LOG}1.log ${RSYSLOG_OUT_LOG}2.log ${RSYSLOG_OUT_LOG}3.log > $RSYSLOG_OUT_LOG
+seq_check
+exit_test
diff --git a/tests/rulesetmultiqueue.sh b/tests/rulesetmultiqueue.sh
new file mode 100755
index 0000000..8b5f9f1
--- /dev/null
+++ b/tests/rulesetmultiqueue.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+# Test for disk-only queue mode
+# This tests defines three rulesets, each one with its own queue. Then, it
+# sends data to them and checks the outcome. Note that we do need to
+# use some custom code as the test driver framework does not (yet?)
+# support multi-output-file operations.
+# added 2009-10-30 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "SunOS" "This test does not work on Solaris. The overall queue
+size check in imdiag requires atomics or mutexes on this platform, which we
+do not use for performance reasons."
+export NUMMESSAGES=60000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+
+# general definition
+$template outfmt,"%msg:F,58:2%\n"
+
+# create the individual rulesets
+$ruleset file1
+$RulesetCreateMainQueue on
+$template dynfile1,"'$RSYSLOG_OUT_LOG'1.log" # trick to use relative path names!
+:msg, contains, "msgnum:" { ?dynfile1;outfmt
+ ./'$RSYSLOG_OUT_LOG'
+}
+
+$ruleset file2
+$RulesetCreateMainQueue on
+$template dynfile2,"'$RSYSLOG_OUT_LOG'2.log" # trick to use relative path names!
+:msg, contains, "msgnum:" { ?dynfile2;outfmt
+ ./'$RSYSLOG_OUT_LOG'
+}
+
+$ruleset file3
+$RulesetCreateMainQueue on
+$template dynfile3,"'$RSYSLOG_OUT_LOG'3.log" # trick to use relative path names!
+:msg, contains, "msgnum:" { ?dynfile3;outfmt
+ ./'$RSYSLOG_OUT_LOG'
+}
+
+# start listeners and bind them to rulesets
+$InputTCPServerBindRuleset file1
+$InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port
+$InputTCPServerRun 0
+
+$InputTCPServerBindRuleset file2
+$InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port2
+$InputTCPServerRun 0
+
+$InputTCPServerBindRuleset file3
+$InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port3
+$InputTCPServerRun 0
+'
+startup
+assign_tcpflood_port2 "$RSYSLOG_DYNNAME.tcpflood_port2"
+assign_rs_port "$RSYSLOG_DYNNAME.tcpflood_port3"
+# now fill the three files (a bit sequentially, but they should
+# still get their share of concurrency - to increase the chance
+# we use three connections per set).
+tcpflood -c3 -p$TCPFLOOD_PORT -m20000 -i0
+tcpflood -c3 -p$TCPFLOOD_PORT2 -m20000 -i20000
+tcpflood -c3 -p$RS_PORT -m20000 -i40000
+
+# in this version of the imdiag, we do not have the capability to poll
+# all queues for emptiness. So we do a sleep in the hopes that this will
+# sufficiently drain the queues. This is race, but the best we currently
+# can do... - rgerhards, 2009-11-05
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+# now consolidate all logs into a single one so that we can use the
+# regular check logic
+cat ${RSYSLOG_OUT_LOG}1.log ${RSYSLOG_OUT_LOG}2.log ${RSYSLOG_OUT_LOG}3.log > $RSYSLOG_OUT_LOG
+seq_check
+exit_test
diff --git a/tests/set-envvars.in b/tests/set-envvars.in
new file mode 100644
index 0000000..573d371
--- /dev/null
+++ b/tests/set-envvars.in
@@ -0,0 +1 @@
+export PYTHON=@PYTHON@
diff --git a/tests/smtradfile-vg.sh b/tests/smtradfile-vg.sh
new file mode 100755
index 0000000..e547c47
--- /dev/null
+++ b/tests/smtradfile-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# addd 2019-04-15 by RGerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:=.}/smtradfile.sh
diff --git a/tests/smtradfile.sh b/tests/smtradfile.sh
new file mode 100755
index 0000000..e47b525
--- /dev/null
+++ b/tests/smtradfile.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+# addd 2019-04-15 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="plugin" plugin="RSYSLOG_TraditionalFileFormat")
+action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+content_check "Mar 1 01:00:00 172.20.245.8 tag msgnum:00000000:"
+exit_test
diff --git a/tests/sndrcv.sh b/tests/sndrcv.sh
new file mode 100755
index 0000000..bf674f7
--- /dev/null
+++ b/tests/sndrcv.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# This tests two rsyslog instances. Instance
+# TWO sends data to instance ONE. A number of messages is injected into
+# the instance 2 and we finally check if all those messages
+# arrived at instance 1.
+# added 2009-11-11 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+# start up the instances
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+# then SENDER sends to this port (not tcpflood!)
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'"
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+
+export RCVR_PORT=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+action(type="omfwd" target="127.0.0.1" protocol="tcp" port="'$RCVR_PORT'")
+' 2
+startup 2
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# do the final check
+seq_check
+
+exit_test
diff --git a/tests/sndrcv_drvr.sh b/tests/sndrcv_drvr.sh
new file mode 100755
index 0000000..ee222f0
--- /dev/null
+++ b/tests/sndrcv_drvr.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+. $srcdir/sndrcv_drvr_noexit.sh $1 $2 $3
diff --git a/tests/sndrcv_drvr_noexit.sh b/tests/sndrcv_drvr_noexit.sh
new file mode 100755
index 0000000..7458edf
--- /dev/null
+++ b/tests/sndrcv_drvr_noexit.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# This is test driver for testing two rsyslog instances. It can be
+# utilized by any test that just needs two instances with different
+# config files, where messages are injected in instance TWO and
+# (with whatever rsyslog mechanism) being relayed over to instance ONE,
+# where they are written to the log file. After the run, the completeness
+# of that log file is checked.
+# The code is almost the same, but the config files differ (probably greatly)
+# for different test cases. As such, this driver needs to be called with the
+# config file name ($2). From that name, the sender and receiver config file
+# names are automatically generated.
+# So: $1 config file name, $2 number of messages
+# environment variable TCPFLOOD_EXTRA_OPTIONS is used to slowdown sending when
+# using UDP (we've seen problems due to UDP message loss if sending with full
+# speed)
+#
+# A note on TLS testing: the current testsuite (in git!) already contains
+# TLS test cases. However, getting these test cases correct is not simple.
+# That's not a problem with the code itself, but rather a problem with
+# synchronization in the test environment. So I have decided to keep the
+# TLS tests in, but not yet actually utilize them. This is most probably
+# left as an exercise for future (devel) releases. -- rgerhards, 2009-11-11
+#
+# added 2009-11-11 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+
+# start up the instances
+export RSYSLOG_DEBUGLOG="log"
+startup $1_rcvr.conf
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+startup $1_sender.conf 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m$2 -i1
+sleep 5 # make sure all data is received in input buffers
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# do the final check
+seq_check 1 $2 $3
diff --git a/tests/sndrcv_dtls_anon_ciphers.sh b/tests/sndrcv_dtls_anon_ciphers.sh
new file mode 100755
index 0000000..bac90da
--- /dev/null
+++ b/tests/sndrcv_dtls_anon_ciphers.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# start up the instances
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+
+add_conf '
+global(
+ debug.whitelist="on"
+ debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imdtls/.libs/imdtls"
+ tls.AuthMode="anon")
+
+input( type="imdtls"
+ tls.tlscfgcmd="CipherString=ECDHE-RSA-AES256-SHA384;Ciphersuites=TLS_AES_256_GCM_SHA384"
+ port="'$PORT_RCVR'")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+generate_conf 2
+add_conf '
+module( load="../plugins/omdtls/.libs/omdtls" )
+
+action( name="omdtls"
+ type="omdtls"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ tls.tlscfgcmd="CipherString=ECDHE-RSA-AES256-SHA384;Ciphersuites=TLS_AES_128_GCM_SHA256"
+)
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg 0 1
+
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# IMPORTANT: this test will generate many error messages. This is exactly it's
+# intent. So do not think something is wrong. The content_check below checks
+# these error codes.
+
+content_check --check-only "TLS library does not support SSL_CONF_cmd"
+ret=$?
+if [ $ret == 0 ]; then
+ echo "SKIP: TLS library does not support SSL_CONF_cmd"
+ skip_test
+else
+ # Kindly check for a failed session
+ content_check "OpenSSL Error Stack"
+ content_check "no shared cipher"
+fi
+
+exit_test
diff --git a/tests/sndrcv_dtls_certvalid-vg.sh b/tests/sndrcv_dtls_certvalid-vg.sh
new file mode 100755
index 0000000..f8b6703
--- /dev/null
+++ b/tests/sndrcv_dtls_certvalid-vg.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+if [ "$(valgrind --version)" == "valgrind-3.11.0" ]; then
+ printf 'This test does NOT work with valgrind-3.11.0 - valgrind always reports\n'
+ printf 'a valgrind-internal bug. So we need to skip it.\n'
+ exit 77
+fi
+export USE_VALGRIND="YES"
+# export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes"
+source ${srcdir:-.}/sndrcv_dtls_certvalid.sh
diff --git a/tests/sndrcv_dtls_certvalid.sh b/tests/sndrcv_dtls_certvalid.sh
new file mode 100755
index 0000000..3f4cc06
--- /dev/null
+++ b/tests/sndrcv_dtls_certvalid.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls}
+export NUMMESSAGES=1000
+export NUMMESSAGESFULL=$NUMMESSAGES
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+# debug.whitelist="on"
+# debug.files=["imdtls.c", "modules.c", "errmsg.c", "action.c"]
+)
+
+module( load="../plugins/imdtls/.libs/imdtls" )
+input( type="imdtls"
+ port="'$PORT_RCVR'")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+# debug.whitelist="on"
+# debug.files=["omdtls.c", "modules.c", "errmsg.c", "action.c"]
+)
+
+# impstats in order to gain insight into error cases
+module(load="../plugins/impstats/.libs/impstats"
+ log.file="'$RSYSLOG_DYNNAME.pstats'"
+ interval="1" log.syslog="off")
+$imdiagInjectDelayMode full
+
+# Load modules
+module( load="../plugins/omdtls/.libs/omdtls" )
+
+local4.* {
+ action( name="omdtls"
+ type="omdtls"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ action.resumeInterval="1"
+ action.resumeRetryCount="2"
+ queue.type="FixedArray"
+ queue.size="10000"
+ queue.dequeueBatchSize="1"
+ queue.minDequeueBatchSize.timeout="1000" # 1 sec
+ queue.timeoutWorkerthreadShutdown="1000" # 1 sec
+ queue.timeoutshutdown="1000"
+ # Slow down, do not lose UDP messages
+ queue.dequeueSlowDown="1000"
+ )
+
+# action( type="omfile" file="'$RSYSLOG_OUT_LOG'")
+ stop
+}
+
+action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'")
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_dtls_certvalid_ciphers.sh b/tests/sndrcv_dtls_certvalid_ciphers.sh
new file mode 100755
index 0000000..93ff49f
--- /dev/null
+++ b/tests/sndrcv_dtls_certvalid_ciphers.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# start up the instances
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+export NUMMESSAGES=1
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imdtls/.libs/imdtls"
+ tls.AuthMode="anon")
+
+input( type="imdtls"
+ tls.tlscfgcmd="CipherString=ECDHE-RSA-AES256-SHA384;Ciphersuites=TLS_AES_256_GCM_SHA384"
+ port="'$PORT_RCVR'")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+generate_conf 2
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+
+module( load="../plugins/omdtls/.libs/omdtls" )
+
+action( name="omdtls"
+ type="omdtls"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ tls.tlscfgcmd="CipherString=ECDHE-RSA-AES128-GCM-SHA256\nCiphersuites=TLS_AES_128_GCM_SHA256"
+)
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg 0 $NUMMESSAGES
+
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# IMPORTANT: this test will generate many error messages. This is exactly it's
+# intent. So do not think something is wrong. The content_check below checks
+# these error codes.
+
+content_check --check-only "TLS library does not support SSL_CONF_cmd"
+ret=$?
+if [ $ret == 0 ]; then
+ echo "SKIP: TLS library does not support SSL_CONF_cmd"
+ skip_test
+else
+ # Kindly check for a failed session
+ content_check "OpenSSL Error Stack"
+ content_check "no shared cipher"
+fi
+
+exit_test
diff --git a/tests/sndrcv_dtls_certvalid_missing.sh b/tests/sndrcv_dtls_certvalid_missing.sh
new file mode 100755
index 0000000..e6908b3
--- /dev/null
+++ b/tests/sndrcv_dtls_certvalid_missing.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls}
+export NUMMESSAGES=1
+# export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+
+add_conf '
+global(
+# debug.whitelist="on"
+# debug.files=["imdtls.c", "modules.c", "errmsg.c", "action.c"]
+)
+
+module( load="../plugins/imdtls/.libs/imdtls" )
+input( type="imdtls"
+ port="'$PORT_RCVR'"
+ tls.cacert="'$srcdir'/tls-certs/ca.pem"
+ tls.mycert="'$srcdir'/tls-certs/cert.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ tls.authmode="certvalid"
+ tls.permittedpeer="rsyslog"
+)
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+
+global(
+# debug.whitelist="on"
+# debug.files=["omdtls.c", "modules.c", "errmsg.c", "action.c"]
+)
+
+# impstats in order to gain insight into error cases
+module(load="../plugins/impstats/.libs/impstats"
+ log.file="'$RSYSLOG_DYNNAME.pstats'"
+ interval="1" log.syslog="off")
+$imdiagInjectDelayMode full
+
+# Load modules
+module( load="../plugins/omdtls/.libs/omdtls" )
+
+local4.* {
+ action( name="omdtls"
+ type="omdtls"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ action.resumeInterval="1"
+ action.resumeRetryCount="2"
+ )
+
+ stop
+}
+
+action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'")
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# Kindly check for a failed session
+content_check "OpenSSL Error Stack"
+content_check "peer did not return a certificate"
+
+exit_test
diff --git a/tests/sndrcv_dtls_certvalid_permitted.sh b/tests/sndrcv_dtls_certvalid_permitted.sh
new file mode 100755
index 0000000..191bf29
--- /dev/null
+++ b/tests/sndrcv_dtls_certvalid_permitted.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls}
+export NUMMESSAGES=1000
+export NUMMESSAGESFULL=$NUMMESSAGES
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+
+add_conf '
+global(
+# debug.whitelist="on"
+# debug.files=["imdtls.c", "modules.c", "errmsg.c", "action.c"]
+)
+
+module( load="../plugins/imdtls/.libs/imdtls" )
+input( type="imdtls"
+ port="'$PORT_RCVR'"
+ tls.cacert="'$srcdir'/tls-certs/ca.pem"
+ tls.mycert="'$srcdir'/tls-certs/cert.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ tls.authmode="name"
+ tls.permittedpeer="rsyslog"
+)
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+
+global(
+# debug.whitelist="on"
+# debug.files=["omdtls.c", "modules.c", "errmsg.c", "action.c"]
+)
+
+# impstats in order to gain insight into error cases
+module(load="../plugins/impstats/.libs/impstats"
+ log.file="'$RSYSLOG_DYNNAME.pstats'"
+ interval="1" log.syslog="off")
+$imdiagInjectDelayMode full
+
+# Load modules
+module( load="../plugins/omdtls/.libs/omdtls" )
+
+local4.* {
+ action( name="omdtls"
+ type="omdtls"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ tls.cacert="'$srcdir'/tls-certs/ca.pem"
+ tls.mycert="'$srcdir'/tls-certs/cert.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ action.resumeInterval="1"
+ action.resumeRetryCount="2"
+ queue.type="FixedArray"
+ queue.size="10000"
+ queue.dequeueBatchSize="1"
+ queue.minDequeueBatchSize.timeout="1000" # 1 sec
+ queue.timeoutWorkerthreadShutdown="1000" # 1 sec
+ queue.timeoutshutdown="1000"
+ # Slow down, do not lose UDP messages
+ queue.dequeueSlowDown="1000"
+ )
+
+ stop
+}
+
+action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'")
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_failover.sh b/tests/sndrcv_failover.sh
new file mode 100755
index 0000000..fd6d656
--- /dev/null
+++ b/tests/sndrcv_failover.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# This tests failover capabilities. Data is sent to a local port, where
+# no process shall listen. Then it fails over to a second instance, then to
+# a file. The second instance is started. So all data should be received
+# there and none be logged to the file.
+# This builds on the basic sndrcv.sh test, but adds a first, failing,
+# location to the conf file.
+# added 2011-06-20 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+export NUMMESSAGES=50000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+export DEAD_PORT=4 # a port unassigned by IANA and very unlikely to be used
+export RSYSLOG_DEBUGLOG="log"
+
+# uncomment for debugging support:
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+# then SENDER sends to this port (not tcpflood!)
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+export PORT_RCVR=$TCPFLOOD_PORT
+generate_conf 2
+add_conf '
+*.* @@127.0.0.1:'$DEAD_PORT' # this must be DEAD
+$ActionExecOnlyWhenPreviousIsSuspended on
+& @@127.0.0.1:'$PORT_RCVR'
+& ./'${RSYSLOG_DYNNAME}'.empty
+$ActionExecOnlyWhenPreviousIsSuspended off
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# do the final check
+seq_check
+
+ls -l ${RSYSLOG_DYNNAME}.empty
+if [[ -s ${RSYSLOG_DYNNAME}.empty ]] ; then
+ echo "FAIL: ${RSYSLOG_DYNNAME}.empty has data. Failover handling failed. Data is written"
+ echo " even though the previous action (in a failover chain!) properly"
+ echo " worked."
+ error_exit 1
+else
+ echo "${RSYSLOG_DYNNAME}.empty is empty - OK"
+fi ;
+exit_test
diff --git a/tests/sndrcv_gzip.sh b/tests/sndrcv_gzip.sh
new file mode 100755
index 0000000..2b56dd5
--- /dev/null
+++ b/tests/sndrcv_gzip.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# This test is similar to tcpsndrcv, but it forwards messages in
+# zlib-compressed format (our own syslog extension).
+# rgerhards, 2009-11-11
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+# then SENDER sends to this port (not tcpflood!)
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+export RCVR_PORT=$TCPFLOOD_PORT
+generate_conf 2
+add_conf '
+*.* @@(z5)127.0.0.1:'$RCVR_PORT'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_kafka.sh b/tests/sndrcv_kafka.sh
new file mode 100755
index 0000000..3b78fed
--- /dev/null
+++ b/tests/sndrcv_kafka.sh
@@ -0,0 +1,125 @@
+#!/bin/bash
+# added 2017-05-03 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export KEEP_KAFKA_RUNNING="YES"
+export TESTMESSAGES=100000
+export TESTMESSAGESFULL=100000
+
+# Generate random topic name
+export RANDTOPIC=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+
+# Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only.
+export EXTRA_EXITCHECK=dumpkafkalogs
+export EXTRA_EXIT=kafka
+
+download_kafka
+stop_zookeeper
+stop_kafka
+start_zookeeper
+start_kafka
+
+create_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+$imdiagInjectDelayMode full
+
+module(load="../plugins/omkafka/.libs/omkafka")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+local4.* {
+ action( name="kafka-fwd"
+ type="omkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ template="outfmt"
+ confParam=[ "compression.codec=none",
+ "socket.timeout.ms=10000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "queue.buffering.max.messages=10000",
+ "enable.auto.commit=true",
+ "message.send.max.retries=1"]
+ topicConfParam=["message.timeout.ms=10000"]
+ partitions.auto="on"
+ closeTimeout="60000"
+ resubmitOnFailure="on"
+ keepFailedMessages="on"
+ failedMsgFile="'$RSYSLOG_OUT_LOG'-failed-'$RANDTOPIC'.data"
+ action.resumeInterval="1"
+ action.resumeRetryCount="10"
+ queue.saveonshutdown="on"
+ )
+ stop
+}
+
+action( type="omfile" file="'$RSYSLOG_DYNNAME.snd.othermsg'")
+'
+
+echo Starting sender instance [omkafka]
+startup
+# ---
+
+# Injection messages now before starting receiver, simply because omkafka will take some time and
+# there is no reason to wait for the receiver to startup first.
+echo Inject messages into rsyslog sender instance
+injectmsg 1 $TESTMESSAGES
+
+# --- Create/Start imkafka receiver config
+export RSYSLOG_DEBUGLOG="log2"
+generate_conf 2
+add_conf '
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+
+module(load="../plugins/imkafka/.libs/imkafka")
+/* Polls messages from kafka server!*/
+input( type="imkafka"
+ topic="'$RANDTOPIC'"
+ broker="localhost:29092"
+ consumergroup="default"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=5000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "enable.partition.eof=false" ]
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if ($msg contains "msgnum:") then {
+ action( type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt" )
+} else {
+ action( type="omfile" file="'$RSYSLOG_DYNNAME.rcv.othermsg'")
+}
+' 2
+
+echo Starting receiver instance [imkafka]
+startup 2
+# ---
+
+echo Stopping sender instance [omkafka]
+shutdown_when_empty
+wait_shutdown
+
+echo Stopping receiver instance [imkafka]
+kafka_wait_group_coordinator
+shutdown_when_empty 2
+wait_shutdown 2
+
+delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181'
+
+# Dump Kafka log | uncomment if needed
+# dump_kafka_serverlog
+
+kafka_check_broken_broker $RSYSLOG_DYNNAME.snd.othermsg
+kafka_check_broken_broker $RSYSLOG_DYNNAME.rcv.othermsg
+
+seq_check 1 $TESTMESSAGESFULL -d
+
+echo success
+exit_test
diff --git a/tests/sndrcv_kafka_multi_topics.sh b/tests/sndrcv_kafka_multi_topics.sh
new file mode 100755
index 0000000..d0e297f
--- /dev/null
+++ b/tests/sndrcv_kafka_multi_topics.sh
@@ -0,0 +1,171 @@
+#!/bin/bash
+# added 2018-08-13 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+export TESTMESSAGES=50000
+export TESTMESSAGESFULL=100000
+
+# Generate random topic name
+export RANDTOPIC1=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+export RANDTOPIC2=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -n 1)
+
+# Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only.
+export EXTRA_EXITCHECK=dumpkafkalogs
+export EXTRA_EXIT=kafka
+echo STEP: Check and Stop previous instances of kafka/zookeeper
+download_kafka
+stop_zookeeper
+stop_kafka
+
+echo STEP: Create kafka/zookeeper instance and topics
+start_zookeeper
+start_kafka
+create_kafka_topic $RANDTOPIC1 '.dep_wrk' '22181'
+create_kafka_topic $RANDTOPIC2 '.dep_wrk' '22181'
+
+# --- Create omkafka sender config
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+$imdiagInjectDelayMode full
+
+module(load="../plugins/omkafka/.libs/omkafka")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+local4.* action( name="kafka-fwd"
+ type="omkafka"
+ topic="'$RANDTOPIC1'"
+ broker="localhost:29092"
+ template="outfmt"
+ confParam=[ "compression.codec=none",
+ "socket.timeout.ms=10000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "queue.buffering.max.messages=10000",
+ "enable.auto.commit=true",
+ "message.send.max.retries=1"]
+ topicConfParam=["message.timeout.ms=10000"]
+ partitions.auto="on"
+ closeTimeout="60000"
+ resubmitOnFailure="on"
+ keepFailedMessages="on"
+ failedMsgFile="'$RSYSLOG_OUT_LOG'-failed-'$RANDTOPIC1'.data"
+ action.resumeInterval="1"
+ action.resumeRetryCount="10"
+ queue.saveonshutdown="on"
+ )
+local4.* action( name="kafka-fwd"
+ type="omkafka"
+ topic="'$RANDTOPIC2'"
+ broker="localhost:29092"
+ template="outfmt"
+ confParam=[ "compression.codec=none",
+ "socket.timeout.ms=10000",
+ "socket.keepalive.enable=true",
+ "reconnect.backoff.jitter.ms=1000",
+ "queue.buffering.max.messages=10000",
+ "enable.auto.commit=true",
+ "message.send.max.retries=1"]
+ topicConfParam=["message.timeout.ms=10000"]
+ partitions.auto="on"
+ closeTimeout="60000"
+ resubmitOnFailure="on"
+ keepFailedMessages="on"
+ failedMsgFile="'$RSYSLOG_OUT_LOG'-failed-'$RANDTOPIC2'.data"
+ action.resumeInterval="1"
+ action.resumeRetryCount="10"
+ queue.saveonshutdown="on"
+ )
+
+syslog.* action(type="omfile" file="'$RSYSLOG_DYNNAME.sender.syslog'")
+'
+
+echo STEP: Starting sender instance [omkafka]
+startup
+# ---
+
+# Injection messages now before starting receiver, simply because omkafka will take some time and
+# there is no reason to wait for the receiver to startup first.
+echo STEP: Inject messages into rsyslog sender instance
+injectmsg 1 $TESTMESSAGES
+
+# --- Create omkafka receiver config
+export RSYSLOG_DEBUGLOG="log2"
+generate_conf 2
+add_conf '
+main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000")
+
+module(load="../plugins/imkafka/.libs/imkafka")
+/* Polls messages from kafka server!*/
+input( type="imkafka"
+ topic="'$RANDTOPIC1'"
+ broker="localhost:29092"
+ consumergroup="default1"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=10000",
+ "enable.partition.eof=false",
+ "reconnect.backoff.jitter.ms=1000",
+ "socket.keepalive.enable=true"]
+ )
+input( type="imkafka"
+ topic="'$RANDTOPIC2'"
+ broker="localhost:29092"
+ consumergroup="default2"
+ confParam=[ "compression.codec=none",
+ "session.timeout.ms=10000",
+ "socket.timeout.ms=10000",
+ "enable.partition.eof=false",
+ "reconnect.backoff.jitter.ms=1000",
+ "socket.keepalive.enable=true"]
+ )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if ($msg contains "msgnum:") then {
+ action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" )
+}
+
+syslog.* action(type="omfile" file="'$RSYSLOG_DYNNAME.receiver.syslog'")
+' 2
+
+echo STEP: Starting receiver instance [imkafka]
+startup 2
+# ---
+
+echo STEP: Stopping sender instance [omkafka]
+shutdown_when_empty
+wait_shutdown
+
+echo STEP: Stopping receiver instance [imkafka]
+kafka_wait_group_coordinator
+shutdown_when_empty 2
+wait_shutdown 2
+
+echo STEP: delete kafka topics
+delete_kafka_topic $RANDTOPIC1 '.dep_wrk' '22181'
+delete_kafka_topic $RANDTOPIC2 '.dep_wrk' '22181'
+
+kafka_check_broken_broker "$RSYSLOG_DYNNAME.sender.syslog"
+kafka_check_broken_broker "$RSYSLOG_DYNNAME.receiver.syslog"
+
+# Dump Kafka log | uncomment if needed
+# dump_kafka_serverlog
+
+# Do the final sequence check
+seq_check 1 $TESTMESSAGES -d
+
+linecount=$(wc -l < ${RSYSLOG_OUT_LOG})
+if [ $linecount -ge $TESTMESSAGESFULL ]; then
+ echo "Info: Count correct: $linecount"
+else
+ echo "Count error detected in $RSYSLOG_OUT_LOG"
+ echo "number of lines in file: $linecount"
+ error_exit 1
+fi
+
+echo success
+exit_test
diff --git a/tests/sndrcv_omsnmpv1_udp.sh b/tests/sndrcv_omsnmpv1_udp.sh
new file mode 100755
index 0000000..a259e96
--- /dev/null
+++ b/tests/sndrcv_omsnmpv1_udp.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# alorbach, 2019-11-27
+# Required Packages
+# pip install pysnmp
+#
+# Ubuntu 18 Packages needed
+# apt install snmp libsnmp-dev snmp-mibs-downloader
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export TESTMESSAGES=10
+
+generate_conf
+export PORT_SNMP="$(get_free_port)"
+# Start SNMP Trap Receiver
+snmp_start_trapreceiver ${PORT_SNMP} ${RSYSLOG_OUT_LOG}
+
+add_conf '
+module( load="../plugins/imtcp/.libs/imtcp")
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+module( load="../plugins/omsnmp/.libs/omsnmp" )
+
+# set up the action
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omsnmp"
+ name="name"
+ server="127.0.0.1"
+ port="'${PORT_SNMP}'"
+ version="0"
+ community="public"
+ enterpriseOID="1.3.6.1.2.1.192.0.1"
+ messageOID="1.3.6.1.2.1.192.1.2.1.11"
+ TrapType="6"
+ specificType="0"
+ )
+'
+startup
+tcpflood -p$TCPFLOOD_PORT -m${TESTMESSAGES}
+netstat -l
+
+shutdown_when_empty
+wait_shutdown
+snmp_stop_trapreceiver
+content_count_check "msgnum:" ${TESTMESSAGES}
+exit_test
diff --git a/tests/sndrcv_omsnmpv1_udp_dynsource.sh b/tests/sndrcv_omsnmpv1_udp_dynsource.sh
new file mode 100755
index 0000000..1f3e886
--- /dev/null
+++ b/tests/sndrcv_omsnmpv1_udp_dynsource.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# alorbach, 2019-11-27
+# Required Packages
+# pip install pysnmp
+#
+# Ubuntu 18 Packages needed
+# apt install snmp libsnmp-dev snmp-mibs-downloader
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export TESTMESSAGES=10
+
+generate_conf
+export PORT_SNMP="$(get_free_port)"
+# Start SNMP Trap Receiver
+snmp_start_trapreceiver ${PORT_SNMP} ${RSYSLOG_OUT_LOG}
+
+add_conf '
+module( load="../plugins/imtcp/.libs/imtcp")
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+module( load="../plugins/omsnmp/.libs/omsnmp" )
+
+# set up templates
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+# Set Custom Host property
+set $!custom_host = "8.8.8.8";
+template(name="dynsource" type="list") {
+ property(name="$!custom_host")
+}
+
+# set up the action
+:msg, contains, "msgnum:" action( type="omsnmp"
+ name="name"
+ server="127.0.0.1"
+ port="'${PORT_SNMP}'"
+ version="0"
+ community="public"
+ enterpriseOID="1.3.6.1.2.1.192.0.1"
+ messageOID="1.3.6.1.2.1.192.1.2.1.11"
+ TrapType="6"
+ specificType="0"
+ snmpv1dynsource="dynsource"
+ )
+'
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m${TESTMESSAGES}
+
+shutdown_when_empty
+wait_shutdown
+snmp_stop_trapreceiver
+content_count_check "msgnum:" ${TESTMESSAGES}
+content_count_check "8.8.8.8" ${TESTMESSAGES}
+exit_test
diff --git a/tests/sndrcv_omsnmpv1_udp_invalidoid.sh b/tests/sndrcv_omsnmpv1_udp_invalidoid.sh
new file mode 100755
index 0000000..4197209
--- /dev/null
+++ b/tests/sndrcv_omsnmpv1_udp_invalidoid.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# alorbach, 2019-11-27
+# Required Packages
+# pip install pysnmp
+#
+# Ubuntu 18 Packages needed
+# apt install snmp libsnmp-dev
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export TESTMESSAGES=1
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.omsnmp.debuglog"
+generate_conf
+export PORT_SNMP="$(get_free_port)"
+# Start SNMP Trap Receiver
+snmp_start_trapreceiver ${PORT_SNMP} ${RSYSLOG_OUT_LOG}
+
+add_conf '
+module( load="../plugins/imtcp/.libs/imtcp")
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+module( load="../plugins/omsnmp/.libs/omsnmp" )
+
+# set up the action
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omsnmp"
+ name="name"
+ server="127.0.0.1"
+ port="'${PORT_SNMP}'"
+ version="0"
+ community="public"
+ enterpriseOID="1337.1.3.3.7.1.3.3.7"
+ messageOID="invalidOIDstring"
+ TrapType="5"
+ specificType="0"
+ )
+'
+startup
+tcpflood -p'$TCPFLOOD_PORT' -m${TESTMESSAGES}
+
+shutdown_when_empty
+wait_shutdown
+snmp_stop_trapreceiver
+content_check "Parsing SyslogMessageOID failed" ${RSYSLOG_DYNNAME}.started
+content_check "Unknown Object Identifier" ${RSYSLOG_DYNNAME}.started
+exit_test
diff --git a/tests/sndrcv_omudpspoof-bigmsg.sh b/tests/sndrcv_omudpspoof-bigmsg.sh
new file mode 100755
index 0000000..6d61793
--- /dev/null
+++ b/tests/sndrcv_omudpspoof-bigmsg.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+# This runs sends and receives big messages via OMUDPSPOOF
+# added 2020-04-07 alorbach
+# This file is part of the rsyslog project, released under GPLv3
+echo This test must be run as root [raw socket access required]
+if [ "$EUID" -ne 0 ]; then
+ exit 77 # Not root, skip this test
+fi
+export TCPFLOOD_EXTRA_OPTS="-b1 -W1"
+export NUMMESSAGES=1
+export MESSAGESIZE=65000 #65000 #32768 #16384
+#export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+#export RSYSLOG_DEBUGLOG="log"
+
+. ${srcdir:=.}/diag.sh init
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_UDP="$(get_free_port)"
+
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+global (
+ maxMessageSize="64k"
+)
+
+input(type="imudp" port="'$PORT_UDP'" ruleset="rsImudp")
+$template outfmt,"%msg%\n"
+
+ruleset(name="rsImudp") {
+ action( name="UDPOUT"
+ type="omfile"
+ file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+'
+startup
+
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+module(load="../plugins/omudpspoof/.libs/omudpspoof")
+
+global (
+ maxMessageSize="64k"
+)
+
+# this listener is for message generation by the test framework!
+input(type="imtcp" port="'$TCPFLOOD_PORT'" ruleset="rsImtcp")
+
+$template spoofaddr,"127.0.0.1"
+
+ruleset(name="rsImtcp") {
+ action( name="MTUTEST"
+ type="omudpspoof"
+ Target="127.0.0.1"
+ Port="'$PORT_UDP'"
+ SourceTemplate="spoofaddr"
+ mtu="1500")
+# for comparison only -> action(name="MTUTEST" type="omfwd" Target="127.0.0.1" Port="'$PORT_UDP'")
+}
+
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+# tcpflood -m$NUMMESSAGES -i1 -d 1024
+tcpflood -m$NUMMESSAGES -i1 -d $MESSAGESIZE
+
+sleep 5 # make sure all data is received in input buffers
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# do the final check
+content_count_check "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ${NUMMESSAGES}
diff --git a/tests/sndrcv_omudpspoof.sh b/tests/sndrcv_omudpspoof.sh
new file mode 100755
index 0000000..d46be1a
--- /dev/null
+++ b/tests/sndrcv_omudpspoof.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# This runs sends and receives messages via UDP to the standard
+# ports. Note that with UDP we can always have message loss. While this is
+# less likely in a local environment, we strongly limit the amount of data
+# we send in the hope to not lose any messages. However, failure of this
+# test does not necessarily mean that the code is wrong (but it is very likely!)
+# added 2009-11-11 by Rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo \[sndrcv_omudpspoof.sh\]: testing sending and receiving via omudp
+echo This test must be run as root [raw socket access required]
+if [ "$EUID" -ne 0 ]; then
+ exit 77 # Not root, skip this test
+fi
+export TCPFLOOD_EXTRA_OPTS="-b1 -W1"
+
+# uncomment for debugging support:
+. ${srcdir:=.}/diag.sh init
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+$ModLoad ../plugins/imudp/.libs/imudp
+# then SENDER sends to this port (not tcpflood!)
+$UDPServerRun 514
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'"
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+# this listener is for message generation by the test framework!
+$InputTCPServerRun '$TCPFLOOD_PORT'
+
+$ModLoad ../plugins/omudpspoof/.libs/omudpspoof
+$template spoofaddr,"127.0.0.1"
+
+#begin action definition
+$ActionOMUDPSpoofSourceNameTemplate spoofaddr
+$ActionOMUDPSpoofTargetHost 127.0.0.1
+$ActionOMUDPSpoofSourcePortStart 514
+$ActionOMUDPSpoofSourcePortEnd 514
+*.* :omudpspoof:
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m50 -i1
+sleep 5 # make sure all data is received in input buffers
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# do the final check
+seq_check 1 50
diff --git a/tests/sndrcv_omudpspoof_nonstdpt.sh b/tests/sndrcv_omudpspoof_nonstdpt.sh
new file mode 100755
index 0000000..c61e39c
--- /dev/null
+++ b/tests/sndrcv_omudpspoof_nonstdpt.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# This runs sends and receives messages via UDP to the standard
+# ports. Note that with UDP we can always have message loss. While this is
+# less likely in a local environment, we strongly limit the amount of data
+# we send in the hope to not lose any messages. However, failure of this
+# test does not necessarily mean that the code is wrong (but it is very likely!)
+# added 2009-11-11 by Rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo \[sndrcv_omudpspoof_nonstdpt.sh\]: testing sending and receiving via omudp
+echo This test must be run as root [raw socket access required]
+if [ "$EUID" -ne 0 ]; then
+ exit 77 # Not root, skip this test
+fi
+export TCPFLOOD_EXTRA_OPTS="-b1 -W1"
+
+# uncomment for debugging support:
+. ${srcdir:=.}/diag.sh init
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+$ModLoad ../plugins/imudp/.libs/imudp
+# then SENDER sends to this port (not tcpflood!)
+$UDPServerRun 2514
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'"
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+# this listener is for message generation by the test framework!
+$InputTCPServerRun '$TCPFLOOD_PORT'
+
+$ModLoad ../plugins/omudpspoof/.libs/omudpspoof
+$template spoofaddr,"127.0.0.1"
+
+#begin action definition
+$ActionOMUDPSpoofSourceNameTemplate spoofaddr
+$ActionOMUDPSpoofTargetHost 127.0.0.1
+$ActionOMUDPSpoofTargetPort 2514
+$ActionOMUDPSpoofSourcePortStart 514
+$ActionOMUDPSpoofSourcePortEnd 514
+*.* :omudpspoof:
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m50 -i1
+sleep 5 # make sure all data is received in input buffers
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# do the final check
+seq_check 1 50
diff --git a/tests/sndrcv_ossl_cert_chain.sh b/tests/sndrcv_ossl_cert_chain.sh
new file mode 100755
index 0000000..b5a524c
--- /dev/null
+++ b/tests/sndrcv_ossl_cert_chain.sh
@@ -0,0 +1,76 @@
+#!/bin/bash
+# alorbach, 2019-01-16
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+### This is important, as it must be exactly the same
+### as the ones configured in used certificates
+export HOSTNAME="fedora"
+add_conf '
+global(
+ DefaultNetstreamDriver="ossl"
+ DefaultNetstreamDriverCAFile="'$srcdir/testsuites/certchain/ca-cert.pem'"
+ DefaultNetstreamDriverCertFile="'$srcdir/testsuites/certchain/server-cert.pem'"
+ DefaultNetstreamDriverKeyFile="'$srcdir/testsuites/certchain/server-key.pem'"
+ NetstreamDriverCAExtraFiles="'$srcdir/testsuites/certchain/ca-root-cert.pem'"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ PermittedPeer="'$HOSTNAME'"
+ StreamDriver.AuthMode="x509/name" )
+# then SENDER sends to this port (not tcpflood!)
+input( type="imtcp" port="'$PORT_RCVR'" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)"
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/certchain/ca-root-cert.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/certchain/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/certchain/client-key.pem'"
+)
+
+# Note: no TLS for the listener, this is for tcpflood!
+$ModLoad ../plugins/imtcp/.libs/imtcp
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+# set up the action
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ StreamDriver="ossl"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="x509/name"
+ StreamDriverPermittedPeers="'$HOSTNAME'"
+ )
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m$NUMMESSAGES -i1
+wait_file_lines
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 $NUMMESSAGES
+exit_test
diff --git a/tests/sndrcv_relp-vg-rcvr.sh b/tests/sndrcv_relp-vg-rcvr.sh
new file mode 100755
index 0000000..030d35c
--- /dev/null
+++ b/tests/sndrcv_relp-vg-rcvr.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+# added 2022-06-21 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+# CHECK VALGRIND MINIMUM VERSION | MIN 3.14.0
+VALGRINDVER=$(valgrind --version)
+VALGRINDVERMAJOR=$(echo $VALGRINDVER | cut -d'-' -f2 | cut -d'.' -f1)
+VALGRINDVERMINOR=$(echo $VALGRINDVER | cut -d'-' -f2 | cut -d'.' -f2)
+if [ "$VALGRINDVERMAJOR" -lt 3 ] || { [ "$VALGRINDVERMAJOR" -eq 3 ] && [ "$VALGRINDVERMINOR" -lt 15 ]; }; then
+ printf 'This test does NOT work with versions below valgrind-3.15.0 (missing --keep-debuginfo) - Installed valgrind version is '
+ printf $VALGRINDVER
+ printf '\n'
+ exit 77
+fi
+
+export NUMMESSAGES=5000
+export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes --leak-check=full"
+########## receiver ##########
+export RSYSLOG_DEBUG="debug nostdout"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+input(type="imrelp" port="'$PORT_RCVR'")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup_vg
+printf "#### RECEIVER STARTED\n\n"
+
+########## sender ##########
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+generate_conf 2
+add_conf '
+module(load="../plugins/omrelp/.libs/omrelp")
+
+action(type="omrelp" name="omrelp" target="127.0.0.1" port="'$PORT_RCVR'")
+' 2
+
+startup 2
+printf "#### SENDER STARTED\n\n"
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 0 $NUMMESSAGES
+
+shutdown_when_empty 2
+wait_shutdown 2
+
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown_vg
+seq_check
+check_exit_vg
+
+exit_test
diff --git a/tests/sndrcv_relp-vg-sender.sh b/tests/sndrcv_relp-vg-sender.sh
new file mode 100755
index 0000000..4b8a6a6
--- /dev/null
+++ b/tests/sndrcv_relp-vg-sender.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+# added 2022-06-21 by alorbach
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+# CHECK VALGRIND MINIMUM VERSION | MIN 3.14.0
+VALGRINDVER=$(valgrind --version)
+VALGRINDVERMAJOR=$(echo $VALGRINDVER | cut -d'-' -f2 | cut -d'.' -f1)
+VALGRINDVERMINOR=$(echo $VALGRINDVER | cut -d'-' -f2 | cut -d'.' -f2)
+if [ "$VALGRINDVERMAJOR" -lt 3 ] || { [ "$VALGRINDVERMAJOR" -eq 3 ] && [ "$VALGRINDVERMINOR" -lt 15 ]; }; then
+ printf 'This test does NOT work with versions below valgrind-3.15.0 (missing --keep-debuginfo) - Installed valgrind version is '
+ printf $VALGRINDVER
+ printf '\n'
+ exit 77
+fi
+
+export NUMMESSAGES=5000
+export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes --leak-check=full"
+########## receiver ##########
+export RSYSLOG_DEBUG="debug nostdout"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+input(type="imrelp" port="'$PORT_RCVR'")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+printf "#### RECEIVER STARTED\n\n"
+
+########## sender ##########
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+generate_conf 2
+add_conf '
+module(load="../plugins/omrelp/.libs/omrelp")
+
+action(type="omrelp" name="omrelp" target="127.0.0.1" port="'$PORT_RCVR'")
+' 2
+
+startup_vg 2
+printf "#### SENDER STARTED\n\n"
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 0 $NUMMESSAGES
+
+printf "#### SENDER SHUTDOWN\n\n"
+shutdown_when_empty 2
+wait_shutdown_vg 2
+check_exit_vg 2
+
+printf "#### RECEIVER SHUTDOWN\n\n"
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+seq_check
+exit_test
diff --git a/tests/sndrcv_relp.sh b/tests/sndrcv_relp.sh
new file mode 100755
index 0000000..a5b957c
--- /dev/null
+++ b/tests/sndrcv_relp.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# added 2013-12-10 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=50000
+########## receiver ##########
+#export RSYSLOG_DEBUG="debug nostdout"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+input(type="imrelp" port="'$PORT_RCVR'")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+printf "#### RECEIVER STARTED\n\n"
+
+########## sender ##########
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+generate_conf 2
+add_conf '
+module(load="../plugins/omrelp/.libs/omrelp")
+
+action(type="omrelp" name="omrelp" target="127.0.0.1" port="'$PORT_RCVR'")
+' 2
+startup 2
+printf "#### SENDER STARTED\n\n"
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 0 50000
+
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_relp_dflt_pt.sh b/tests/sndrcv_relp_dflt_pt.sh
new file mode 100755
index 0000000..8427e09
--- /dev/null
+++ b/tests/sndrcv_relp_dflt_pt.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+# this checks if omrelp works with the default port
+# Note: imrelp requires the port, so we cannot and must not
+# check the "default port"
+# added 2013-12-10 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+relp_port=$(./omrelp_dflt_port)
+if [ $relp_port -lt 1024 ]; then
+ if [ "$EUID" -ne 0 ]; then
+ echo relp default port $relp_port is privileged
+ echo need to be root to run this test - skipping
+ exit 77
+ fi
+fi
+
+# uncomment for debugging support:
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+# then SENDER sends to this port (not tcpflood!)
+input(type="imrelp" port="'$relp_port'")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)"
+add_conf '
+module(load="../plugins/omrelp/.libs/omrelp")
+
+action(type="omrelp" target="127.0.0.1")
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 1 50000
+
+# shut down sender
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 50000
+exit_test
diff --git a/tests/sndrcv_relp_rebind.sh b/tests/sndrcv_relp_rebind.sh
new file mode 100755
index 0000000..2e8cd93
--- /dev/null
+++ b/tests/sndrcv_relp_rebind.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# added 2017-09-29 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+echo testing sending and receiving via relp w/ rebind interval
+# uncomment for debugging support:
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+# then SENDER sends to this port (not tcpflood!)
+input(type="imrelp" port="'$PORT_RCVR'")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)" # TODO: move to diag.sh
+add_conf '
+module(load="../plugins/omrelp/.libs/omrelp")
+
+# We know that a rebind interval of 1 is NOT what you would normally expect in
+# production. However, this stresses the code the most and we have seen that
+# some problems do not reliably occur if we use higher rebind intervals. Thus
+# we consider it to be a good, actually required, setting.
+action(type="omrelp" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'" rebindinterval="1")
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 1 1000
+
+# shut down sender
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 1000
+exit_test
diff --git a/tests/sndrcv_relp_tls-cfgcmd.sh b/tests/sndrcv_relp_tls-cfgcmd.sh
new file mode 100755
index 0000000..d13637b
--- /dev/null
+++ b/tests/sndrcv_relp_tls-cfgcmd.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# added 2019-11-13 by alorbach
+. ${srcdir:=.}/diag.sh init
+require_relpEngineSetTLSLibByName
+export PORT_RCVR="$(get_free_port)"
+export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+module( load="../plugins/imrelp/.libs/imrelp"
+ tls.tlslib="openssl")
+# then SENDER sends to this port (not tcpflood!)
+input( type="imrelp" port="'$PORT_RCVR'" tls="on"
+ tls.tlscfgcmd="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.2
+CipherString=ECDHE-RSA-AES256-GCM-SHA384
+Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.2,-TLSv1.3
+MinProtocol=TLSv1.2
+MaxProtocol=TLSv1.2"
+ )
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+generate_conf 2
+add_conf '
+module( load="../plugins/omrelp/.libs/omrelp"
+ tls.tlslib="openssl")
+
+action( type="omrelp" target="127.0.0.1" port="'$PORT_RCVR'" tls="on"
+ tls.tlscfgcmd="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1.1,-TLSv1.2
+CipherString=DHE-RSA-AES256-SHA
+Protocol=ALL,-SSLv2,-SSLv3,-TLSv1.1,-TLSv1.2,-TLSv1.3
+MinProtocol=TLSv1.1
+MaxProtocol=TLSv1.1" )
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 1 1000
+
+# shut down sender
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+content_check --check-only "relpTcpConnectTLSInit_gnutls" ${RSYSLOG_DEBUGLOG}
+ret=$?
+if [ $ret == 0 ]; then
+ echo "SKIP: LIBRELP was build without OPENSSL Support"
+ skip_test
+fi
+
+content_check --check-only "OpenSSL Version too old" $RSYSLOG_DEBUGLOG
+ret=$?
+if [ $ret == 0 ]; then
+ echo "SKIP: OpenSSL Version too old"
+ skip_test
+else
+ # Kindly check for a failed session
+ content_check "librelp: generic error: ecode 10031" $RSYSLOG_DEBUGLOG
+# content_check "OpenSSL Error Stack:"
+fi
+
+exit_test \ No newline at end of file
diff --git a/tests/sndrcv_relp_tls.sh b/tests/sndrcv_relp_tls.sh
new file mode 100755
index 0000000..35b43a1
--- /dev/null
+++ b/tests/sndrcv_relp_tls.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# added 2013-12-10 by Rgerhards
+# testing sending and receiving via relp with TLS enabled
+# This file is part of the rsyslog project, released under ASL 2.0
+# uncomment for debugging support:
+. ${srcdir:=.}/diag.sh init
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+# then SENDER sends to this port (not tcpflood!)
+input(type="imrelp" port="'$PORT_RCVR'" tls="on")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+module(load="../plugins/omrelp/.libs/omrelp")
+
+action(type="omrelp" target="127.0.0.1" port="'$PORT_RCVR'" tls="on")
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 1 50000
+
+# shut down sender
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# do the final check
+seq_check 1 50000
+
+exit_test
diff --git a/tests/sndrcv_relp_tls_certvalid.sh b/tests/sndrcv_relp_tls_certvalid.sh
new file mode 100755
index 0000000..728b2a1
--- /dev/null
+++ b/tests/sndrcv_relp_tls_certvalid.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# added 2018-09-13 by PascalWithopf
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+# then SENDER sends to this port (not tcpflood!)
+input(type="imrelp" port="'$PORT_RCVR'" tls="on"
+ tls.cacert="'$srcdir'/tls-certs/ca.pem"
+ tls.mycert="'$srcdir'/tls-certs/cert.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ tls.authmode="certvalid"
+ tls.permittedpeer="rsyslog")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+module(load="../plugins/omrelp/.libs/omrelp")
+
+:msg, contains, "msgnum:" action(type="omrelp"
+ target="127.0.0.1" port="'$PORT_RCVR'" tls="on"
+ tls.cacert="'$srcdir'/tls-certs/ca.pem"
+ tls.mycert="'$srcdir'/tls-certs/cert.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ tls.authmode="certvalid"
+ tls.permittedpeer="rsyslog")
+action(type="omfile" file="'$RSYSLOG_DYNNAME.errmsgs'")
+' 2
+startup 2
+
+grep "omrelp error: invalid authmode" $RSYSLOG_DYNNAME.errmsgs > /dev/null
+if [ $? -eq 0 ]; then
+ echo "SKIP: librelp does not support "certvalid" auth mode"
+ # mini-cleanup to not leave dangling processes
+ shutdown_immediate 2
+ shutdown_immediate
+ rm $RSYSLOG_DYNNAME* &> /dev/null
+ exit 77
+fi
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 1 50000
+
+# shut down sender
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 50000
+exit_test
diff --git a/tests/sndrcv_relp_tls_chainedcert.sh b/tests/sndrcv_relp_tls_chainedcert.sh
new file mode 100755
index 0000000..7755a93
--- /dev/null
+++ b/tests/sndrcv_relp_tls_chainedcert.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# addd 2020-08-25 by alorbach, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+require_relpEngineVersion "1.7.0"
+export NUMMESSAGES=1000
+export TB_TEST_MAX_RUNTIME=30
+
+# uncomment for debugging support:
+# export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+# export RSYSLOG_DEBUGLOG="log"
+
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+module( load="../plugins/imrelp/.libs/imrelp"
+ tls.tlslib="openssl")
+
+# then SENDER sends to this port (not tcpflood!)
+input(type="imrelp" port="'$PORT_RCVR'"
+ tls="on"
+ tls.mycert="'$srcdir'/tls-certs/certchained.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ tls.authmode="certvalid"
+ tls.permittedpeer="rsyslog")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+module( load="../plugins/omrelp/.libs/omrelp"
+ tls.tlslib="openssl")
+
+:msg, contains, "msgnum:" action(type="omrelp"
+ target="127.0.0.1" port="'$PORT_RCVR'"
+ tls="on"
+ tls.mycert="'$srcdir'/tls-certs/certchained.pem"
+ tls.myprivkey="'$srcdir'/tls-certs/key.pem"
+ tls.authmode="certvalid"
+ tls.permittedpeer="rsyslog")
+action(type="omfile" file="'$RSYSLOG_DYNNAME.errmsgs'")
+' 2
+startup 2
+
+if grep "omrelp error: invalid authmode" < "$RSYSLOG_DYNNAME.errmsgs" ; then
+ echo "SKIP: librelp does not support "certvalid" auth mode"
+ # mini-cleanup to not leave dangling processes
+ shutdown_immediate 2
+ shutdown_immediate
+ rm $RSYSLOG_DYNNAME* &> /dev/null
+ exit 77
+fi
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 1 $NUMMESSAGES
+
+# shut down sender
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 $NUMMESSAGES
+exit_test
diff --git a/tests/sndrcv_relp_tls_prio.sh b/tests/sndrcv_relp_tls_prio.sh
new file mode 100755
index 0000000..78bdadd
--- /dev/null
+++ b/tests/sndrcv_relp_tls_prio.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# added 2013-12-10 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+echo testing sending and receiving via relp with TLS enabled and priority string set
+
+# uncomment for debugging support:
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+module(load="../plugins/imrelp/.libs/imrelp")
+# then SENDER sends to this port (not tcpflood!)
+input(type="imrelp" port="'$PORT_RCVR'" tls="on" tls.prioritystring="NORMAL:+ANON-DH")
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+module(load="../plugins/omrelp/.libs/omrelp")
+
+action(type="omrelp" target="127.0.0.1" port="'$PORT_RCVR'" tls="on" tls.prioritystring="NORMAL:+ANON-DH")
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 1 50000
+
+# shut down sender
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 50000
+exit_test
diff --git a/tests/sndrcv_tls_anon_hostname.sh b/tests/sndrcv_tls_anon_hostname.sh
new file mode 100755
index 0000000..8d0efff
--- /dev/null
+++ b/tests/sndrcv_tls_anon_hostname.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+# rgerhards, 2011-04-04
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=25000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+# start up the instances
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="gtls"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RCVR_PORT=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="gtls"
+)
+
+# set up the action
+$ActionSendStreamDriverMode 1 # require TLS for the connection
+$ActionSendStreamDriverAuthMode anon
+*.* @@localhost:'$RCVR_PORT'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_tls_anon_ipv4.sh b/tests/sndrcv_tls_anon_ipv4.sh
new file mode 100755
index 0000000..9a9fc3d
--- /dev/null
+++ b/tests/sndrcv_tls_anon_ipv4.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# rgerhards, 2011-04-04
+# testing sending and receiving via TLS with anon auth using bare ipv4, no SNI
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=25000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+# uncomment for debugging support:
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="gtls"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RCVR_PORT=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+ defaultNetstreamDriver="gtls"
+)
+
+# set up the action
+$DefaultNetstreamDriver gtls # use gtls netstream driver
+$ActionSendStreamDriverMode 1 # require TLS for the connection
+$ActionSendStreamDriverAuthMode anon
+*.* @@127.0.0.1:'$RCVR_PORT'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_tls_anon_ipv6.sh b/tests/sndrcv_tls_anon_ipv6.sh
new file mode 100755
index 0000000..1770b17
--- /dev/null
+++ b/tests/sndrcv_tls_anon_ipv6.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# rgerhards, 2011-04-04
+# testing sending and receiving via TLS with anon auth using bare ipv6, no SNI
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+. $srcdir/diag.sh check-ipv6-available
+export NUMMESSAGES=25000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+
+# start up the instances
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir'/testsuites/x.509/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/testsuites/x.509/client-cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/testsuites/x.509/client-key.pem"
+ defaultNetstreamDriver="gtls"
+ debug.whitelist="on"
+ debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module(load="../plugins/imtcp/.libs/imtcp" maxSessions="1100"
+ streamDriver.mode="1" streamDriver.authMode="anon")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+#unset RSYSLOG_DEBUG # suppress this debug log, if you want
+export PORT_RCVR=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)" # TODO: move to diag.sh
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+ defaultNetstreamDriver="gtls"
+)
+
+# set up the action
+$DefaultNetstreamDriver gtls # use gtls netstream driver
+$ActionSendStreamDriverMode 1 # require TLS for the connection
+$ActionSendStreamDriverAuthMode anon
+*.* @@[::1]:'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_tls_anon_rebind.sh b/tests/sndrcv_tls_anon_rebind.sh
new file mode 100755
index 0000000..96a6734
--- /dev/null
+++ b/tests/sndrcv_tls_anon_rebind.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+# testing sending and receiving via TLS with anon auth and rebind
+# rgerhards, 2011-04-04
+# This file is part of the rsyslog project, released under GPLv3
+. ${srcdir:=.}/diag.sh init
+# uncomment for debugging support:
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="gtls"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export PORT_RCVR=$TCPFLOOD_PORT # save this, will be rewritten with next config
+
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+ defaultNetstreamDriver="gtls"
+)
+
+# set up the action
+$ActionSendStreamDriverMode 1 # require TLS for the connection
+$ActionSendStreamDriverAuthMode anon
+$ActionSendTCPRebindInterval 50
+*.* @@127.0.0.1:'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 1 25000
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 25000
+exit_test
diff --git a/tests/sndrcv_tls_certless_clientonly.sh b/tests/sndrcv_tls_certless_clientonly.sh
new file mode 100755
index 0000000..8a4e00d
--- /dev/null
+++ b/tests/sndrcv_tls_certless_clientonly.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+# all we want to test is if certless communication works. So we do
+# not need to send many messages.
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+# receiver
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+ defaultNetstreamDriver="gtls"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input( type="imtcp" port="'$PORT_RCVR'" )
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+# sender
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+#export TCPFLOOD_PORT="$(get_free_port)"
+add_conf '
+global(defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'")
+
+# Note: no TLS for the listener, this is for tcpflood!
+$ModLoad ../plugins/imtcp/.libs/imtcp
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+action( type="omfwd" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'"
+ StreamDriver="gtls" StreamDriverMode="1" StreamDriverAuthMode="anon")
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m$NUMMESSAGES -i1
+wait_file_lines
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 $NUMMESSAGES
+exit_test
diff --git a/tests/sndrcv_tls_certvalid.sh b/tests/sndrcv_tls_certvalid.sh
new file mode 100755
index 0000000..b00e292
--- /dev/null
+++ b/tests/sndrcv_tls_certvalid.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls}
+export NUMMESSAGES=10000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="'$RS_TLS_DRIVER'"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="'$RS_TLS_DRIVER'"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/certvalid" )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+export PORT_RCVR=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="'$RS_TLS_DRIVER'"
+)
+
+# set up the action
+$ActionSendStreamDriverMode 1 # require TLS for the connection
+$ActionSendStreamDriverAuthMode x509/certvalid
+*.* @@127.0.0.1:'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_tls_certvalid_action_level.sh b/tests/sndrcv_tls_certvalid_action_level.sh
new file mode 100755
index 0000000..561af6e
--- /dev/null
+++ b/tests/sndrcv_tls_certvalid_action_level.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls}
+export NUMMESSAGES=10000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+ defaultNetstreamDriver="'$RS_TLS_DRIVER'"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="'$RS_TLS_DRIVER'"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/certvalid" )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+export PORT_RCVR=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="'$RS_TLS_DRIVER'"
+)
+
+action(type="omfwd" target="127.0.0.1" port="'$PORT_RCVR'" protocol="tcp"
+ streamDriverMode="1"
+ streamDriverAuthMode="x509/certvalid"
+ streamdriver.cafile="'$srcdir'/tls-certs/ca.pem"
+ streamdriver.keyfile="'$srcdir'/tls-certs/key.pem"
+ streamdriver.certfile="'$srcdir'/tls-certs/cert.pem"
+)
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_tls_certvalid_expired.sh b/tests/sndrcv_tls_certvalid_expired.sh
new file mode 100755
index 0000000..bab916c
--- /dev/null
+++ b/tests/sndrcv_tls_certvalid_expired.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls}
+
+# start up the instances
+# export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="'$RS_TLS_DRIVER'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="'$RS_TLS_DRIVER'"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/certvalid"
+ StreamDriver.PermitExpiredCerts="off"
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+export PORT_RCVR=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-expired-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-expired-key.pem'"
+ defaultNetstreamDriver="'$RS_TLS_DRIVER'"
+)
+
+# set up the action
+$ActionSendStreamDriverMode 1 # require TLS for the connection
+$ActionSendStreamDriverAuthMode anon
+*.* @@127.0.0.1:'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+content_check --regex "not permitted to talk to peer '.*', certificate invalid: certificate expired"
+
+exit_test
diff --git a/tests/sndrcv_tls_certvalid_expired_defaultmode.sh b/tests/sndrcv_tls_certvalid_expired_defaultmode.sh
new file mode 100755
index 0000000..47aaa10
--- /dev/null
+++ b/tests/sndrcv_tls_certvalid_expired_defaultmode.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+
+# uncomment for debugging support:
+. ${srcdir:=.}/diag.sh init
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-expired-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-expired-key.pem'"
+ defaultNetstreamDriver="gtls"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon"
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+'
+startup
+export PORT_RCVR=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="gtls"
+)
+
+# set up the action
+$ActionSendStreamDriverMode 1 # require TLS for the connection
+$ActionSendStreamDriverAuthMode x509/certvalid
+*.* @@127.0.0.1:'$PORT_RCVR'
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+content_check --regex "not permitted to talk to peer '.*', certificate invalid: certificate expired"
+
+exit_test
diff --git a/tests/sndrcv_tls_certvalid_revoked.sh b/tests/sndrcv_tls_certvalid_revoked.sh
new file mode 100755
index 0000000..b01699e
--- /dev/null
+++ b/tests/sndrcv_tls_certvalid_revoked.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls}
+
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultnetstreamdriverCRLfile="'$srcdir/testsuites/x.509/crl.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert-new.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="'$RS_TLS_DRIVER'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="'$RS_TLS_DRIVER'"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/certvalid"
+ StreamDriver.PermitExpiredCerts="off"
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+export PORT_RCVR=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultnetstreamdriverCRLfile="'$srcdir/testsuites/x.509/crl.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-revoked.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-revoked-key.pem'"
+ defaultNetstreamDriver="'$RS_TLS_DRIVER'"
+)
+
+# set up the action
+$ActionSendStreamDriverMode 1 # require TLS for the connection
+$ActionSendStreamDriverAuthMode anon
+*.* @@127.0.0.1:'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+if [ -z "$TEXT_TO_CHECK" ]; then
+ TEXT_TO_CHECK="not permitted to talk to peer '.*', certificate invalid: certificate revoked"
+fi
+content_check --regex "$TEXT_TO_CHECK"
+
+exit_test
diff --git a/tests/sndrcv_tls_client_missing_cert.sh b/tests/sndrcv_tls_client_missing_cert.sh
new file mode 100755
index 0000000..7045416
--- /dev/null
+++ b/tests/sndrcv_tls_client_missing_cert.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls}
+
+# start up the instances
+# export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="'$RS_TLS_DRIVER'"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="'$RS_TLS_DRIVER'"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/certvalid"
+ StreamDriver.PermitExpiredCerts="off"
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+export PORT_RCVR=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(
+/*
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-expired-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-expired-key.pem'"
+*/
+ defaultNetstreamDriver="'$RS_TLS_DRIVER'"
+)
+
+# set up the action
+$ActionSendStreamDriverMode 1 # require TLS for the connection
+$ActionSendStreamDriverAuthMode anon
+*.* @@127.0.0.1:'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+content_check --regex "peer .* did not provide a certificate,"
+
+exit_test
diff --git a/tests/sndrcv_tls_gtls_serveranon_gtls_clientanon.sh b/tests/sndrcv_tls_gtls_serveranon_gtls_clientanon.sh
new file mode 100755
index 0000000..d8d13a4
--- /dev/null
+++ b/tests/sndrcv_tls_gtls_serveranon_gtls_clientanon.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# alorbach, 2019-01-16
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+export RCVR_PORT=$TCPFLOOD_PORT
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$RCVR_PORT'"
+ StreamDriver="gtls"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="anon"
+ )
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_tls_gtls_serveranon_ossl_clientanon.sh b/tests/sndrcv_tls_gtls_serveranon_ossl_clientanon.sh
new file mode 100755
index 0000000..08e5cf1
--- /dev/null
+++ b/tests/sndrcv_tls_gtls_serveranon_ossl_clientanon.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# alorbach, 2019-01-16
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input( type="imtcp" port="'$PORT_RCVR'" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)"
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+)
+
+# Note: no TLS for the listener, this is for tcpflood!
+module( load="../plugins/imtcp/.libs/imtcp")
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# set up the action
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ StreamDriver="ossl"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="anon"
+ )
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m$NUMMESSAGES -i1
+wait_file_lines
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 $NUMMESSAGES
+exit_test
diff --git a/tests/sndrcv_tls_gtls_servercert_gtls_clientanon.sh b/tests/sndrcv_tls_gtls_servercert_gtls_clientanon.sh
new file mode 100755
index 0000000..b473edf
--- /dev/null
+++ b/tests/sndrcv_tls_gtls_servercert_gtls_clientanon.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# alorbach, 2019-01-16
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls"
+ StreamDriver.Mode="1" StreamDriver.AuthMode="anon" )
+
+# then SENDER sends to this port (not tcpflood!)
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+export RCVR_PORT=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'")
+
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$RCVR_PORT'"
+ StreamDriver="gtls"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="x509/certvalid"
+ )
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+wait_file_lines
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_tls_gtls_servercert_gtls_clientanon_legacy.sh b/tests/sndrcv_tls_gtls_servercert_gtls_clientanon_legacy.sh
new file mode 100755
index 0000000..b8cc1df
--- /dev/null
+++ b/tests/sndrcv_tls_gtls_servercert_gtls_clientanon_legacy.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# all we want to test is if certless communication works. So we do
+# not need to send many messages.
+# This test checks legacy statements which are often given as
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=5000
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+# receiver
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+ defaultNetstreamDriver="gtls"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input( type="imtcp" port="'$PORT_RCVR'" )
+
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+startup
+
+# sender
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+#export TCPFLOOD_PORT="$(get_free_port)"
+add_conf '
+# Note: no TLS for the listener, this is for tcpflood!
+$ModLoad ../plugins/imtcp/.libs/imtcp
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# NOTE: do NOT change legacy statements - they are used intentionally
+$DefaultNetstreamDriverCAFile '$srcdir/tls-certs/ca.pem'
+$ActionSendStreamDriver gtls
+$ActionSendStreamDriverMode 1
+$ActionSendStreamDriverAuthMode x509/name
+$ActionSendStreamDriverPermittedPeer *.rsyslog.com
+*.* @@localhost:'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m$NUMMESSAGES -i1
+wait_file_lines
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 $NUMMESSAGES
+exit_test
diff --git a/tests/sndrcv_tls_gtls_servercert_ossl_clientanon.sh b/tests/sndrcv_tls_gtls_servercert_ossl_clientanon.sh
new file mode 100755
index 0000000..1cf2f44
--- /dev/null
+++ b/tests/sndrcv_tls_gtls_servercert_ossl_clientanon.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# alorbach, 2019-01-16
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="gtls"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input( type="imtcp" port="'$PORT_RCVR'" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)"
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+)
+
+# Note: no TLS for the listener, this is for tcpflood!
+module( load="../plugins/imtcp/.libs/imtcp")
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# set up the action
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ StreamDriver="ossl"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="x509/certvalid"
+ )
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m$NUMMESSAGES -i1
+wait_file_lines
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 $NUMMESSAGES
+exit_test
diff --git a/tests/sndrcv_tls_ossl_anon_ciphers.sh b/tests/sndrcv_tls_ossl_anon_ciphers.sh
new file mode 100755
index 0000000..80201ed
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_anon_ciphers.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# start up the instances
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriver="ossl"
+ debug.whitelist="on"
+ debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon"
+ StreamDriver.PermitExpiredCerts="off"
+ gnutlsPriorityString="CipherString=ECDHE-RSA-AES256-SHA384;Ciphersuites=TLS_AES_256_GCM_SHA384"
+ )
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+export PORT_RCVR=$TCPFLOOD_PORT # save this, will be rewritten with next config
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriver="ossl"
+)
+
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="anon"
+ gnutlsPriorityString="CipherString=ECDHE-RSA-AES256-SHA384;Ciphersuites=TLS_AES_128_GCM_SHA256"
+)
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg 0 1
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# IMPORTANT: this test will generate many error messages. This is exactly it's
+# intent. So do not think something is wrong. The content_check below checks
+# these error codes.
+
+content_check --check-only "TLS library does not support SSL_CONF_cmd"
+ret=$?
+if [ $ret == 0 ]; then
+ echo "SKIP: TLS library does not support SSL_CONF_cmd"
+ skip_test
+else
+ # Kindly check for a failed session
+ content_check "OpenSSL Error Stack"
+ content_check "no shared cipher"
+fi
+
+exit_test
diff --git a/tests/sndrcv_tls_ossl_anon_ipv4.sh b/tests/sndrcv_tls_ossl_anon_ipv4.sh
new file mode 100755
index 0000000..8bb4836
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_anon_ipv4.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# testing sending and receiving via TLS with anon auth using bare ipv4, no SNI
+# rgerhards, 2011-04-04
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+if [ "${TARGET:=127.0.0.1}" == "[::1]" ]; then
+. $srcdir/diag.sh check-ipv6-available
+fi
+export NUMMESSAGES=10000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="ossl"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+export PORT_RCVR=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+ defaultNetstreamDriver="ossl"
+)
+
+# set up the action
+$ActionSendStreamDriverMode 1 # require TLS for the connection
+$ActionSendStreamDriverAuthMode anon
+*.* @@'${TARGET}':'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_tls_ossl_anon_ipv6.sh b/tests/sndrcv_tls_ossl_anon_ipv6.sh
new file mode 100755
index 0000000..a021112
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_anon_ipv6.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# addd 2020-01-16 by RGerhards, released under ASL 2.0
+export TARGET="[::1]"
+source ${srcdir:=.}/sndrcv_tls_ossl_anon_ipv4.sh
diff --git a/tests/sndrcv_tls_ossl_anon_rebind.sh b/tests/sndrcv_tls_ossl_anon_rebind.sh
new file mode 100755
index 0000000..6d7aaff
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_anon_rebind.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+# rgerhards, 2011-04-04
+# testing sending and receiving via TLS with anon auth and rebind
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=25000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+# debugging activated to try to solve https://github.com/rsyslog/rsyslog/issues/3256
+export RSYSLOG_DEBUG="debug nostdout"
+test_error_exit_handler() {
+ set -x
+ cat "$RSYSLOG_DYNNAME.receiver.debuglog"
+ cat "$RSYSLOG_DYNNAME.sender.debuglog"
+ set +x
+}
+
+#receiver
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="ossl"
+ debug.whitelist="on"
+ debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action( type="omfile"
+ template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+
+#sender
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+#valgrind="valgrind"
+export PORT_RCVR=$TCPFLOOD_PORT # save TCPFLOOD_PORT, generate_conf will overwrite it!
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="ossl"
+)
+
+# set up the action
+$DefaultNetstreamDriver ossl
+$ActionSendStreamDriverMode 1
+$ActionSendStreamDriverAuthMode anon
+$ActionSendTCPRebindInterval 100
+*.* @@127.0.0.1:'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+export SEQ_CHECK_OPTIONS=-d
+seq_check
+
+exit_test
diff --git a/tests/sndrcv_tls_ossl_certvalid.sh b/tests/sndrcv_tls_ossl_certvalid.sh
new file mode 100755
index 0000000..1cb8325
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_certvalid.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# added 2020-01-17 by RGerhards, released under ASL 2.0
+export RS_TLS_DRIVER=ossl
+source ${srcdir:=.}/sndrcv_tls_certvalid.sh
diff --git a/tests/sndrcv_tls_ossl_certvalid_action_level.sh b/tests/sndrcv_tls_ossl_certvalid_action_level.sh
new file mode 100755
index 0000000..446995b
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_certvalid_action_level.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# added 2020-01-17 by RGerhards, released under ASL 2.0
+export RS_TLS_DRIVER=ossl
+source ${srcdir:=.}/sndrcv_tls_certvalid_action_level.sh
diff --git a/tests/sndrcv_tls_ossl_certvalid_ciphers.sh b/tests/sndrcv_tls_ossl_certvalid_ciphers.sh
new file mode 100755
index 0000000..62fd636
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_certvalid_ciphers.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# start up the instances
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+ defaultNetstreamDriver="ossl"
+ debug.whitelist="on"
+ debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/certvalid"
+ StreamDriver.PermitExpiredCerts="off"
+ gnutlsPriorityString="CipherString=ECDHE-RSA-AES256-GCM-SHA384\nCiphersuites=TLS_AES_256_GCM_SHA384"
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+export PORT_RCVR=$TCPFLOOD_PORT # save this, will be rewritten with next config
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+generate_conf 2
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+ defaultNetstreamDriver="ossl"
+)
+
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="x509/certvalid"
+ gnutlsPriorityString="CipherString=ECDHE-RSA-AES128-GCM-SHA256\nCiphersuites=TLS_AES_128_GCM_SHA256"
+)
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg 0 1
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# IMPORTANT: this test will generate many error messages. This is exactly it's
+# intent. So do not think something is wrong. The content_check below checks
+# these error codes.
+
+content_check --check-only "TLS library does not support SSL_CONF_cmd"
+ret=$?
+if [ $ret == 0 ]; then
+ echo "SKIP: TLS library does not support SSL_CONF_cmd"
+ skip_test
+else
+ # Kindly check for a failed session
+ content_check "OpenSSL Error Stack"
+ content_check "no shared cipher"
+fi
+
+exit_test
diff --git a/tests/sndrcv_tls_ossl_certvalid_expired.sh b/tests/sndrcv_tls_ossl_certvalid_expired.sh
new file mode 100755
index 0000000..5439acf
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_certvalid_expired.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="ossl"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/certvalid"
+ StreamDriver.PermitExpiredCerts="off"
+ )
+
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+export PORT_RCVR=$TCPFLOOD_PORT
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-expired-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-expired-key.pem'"
+ defaultNetstreamDriver="ossl"
+)
+
+# set up the action
+$ActionSendStreamDriverMode 1 # require TLS for the connection
+$ActionSendStreamDriverAuthMode anon
+*.* @@127.0.0.1:'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+content_check "Certificate EXPIRED at depth"
+content_check "OpenSSL Error Stack:"
+exit_test
diff --git a/tests/sndrcv_tls_ossl_certvalid_revoked.sh b/tests/sndrcv_tls_ossl_certvalid_revoked.sh
new file mode 100755
index 0000000..f183fdc
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_certvalid_revoked.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# added 2020-01-17 by RGerhards, released under ASL 2.0
+export RS_TLS_DRIVER=ossl
+#export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+#export RSYSLOG_DEBUGLOG="log"
+source ${srcdir:=.}/sndrcv_tls_certvalid_revoked.sh
diff --git a/tests/sndrcv_tls_ossl_certvalid_tlscommand.sh b/tests/sndrcv_tls_ossl_certvalid_tlscommand.sh
new file mode 100755
index 0000000..b945abe
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_certvalid_tlscommand.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+# export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout"
+# start up the instances
+# export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog"
+generate_conf
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+ defaultNetstreamDriver="ossl"
+# debug.whitelist="on"
+# debug.files=["nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"]
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="x509/certvalid"
+ StreamDriver.PermitExpiredCerts="off"
+ gnutlsPriorityString="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.2\nOptions=Bugs"
+ )
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+export PORT_RCVR=$TCPFLOOD_PORT # save this, will be rewritten with next config
+export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog"
+generate_conf 2
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+ defaultNetstreamDriver="ossl"
+)
+
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="x509/certvalid"
+ gnutlsPriorityString="Protocol=-ALL,TLSv1.2"
+)
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2 0 1
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# IMPORTANT: this test will generate many error messages. This is exactly it's
+# intent. So do not think something is wrong. The content_check below checks
+# these error codes.
+
+content_check --check-only "TLS library does not support SSL_CONF_cmd"
+ret=$?
+if [ $ret == 0 ]; then
+ echo "SKIP: TLS library does not support SSL_CONF_cmd"
+ skip_test
+else
+ content_check --check-only "SSL_ERROR_SYSCALL"
+ ret=$?
+ if [ $ret == 0 ]; then
+ # Found SSL_ERROR_SYSCALL errorcode, no further check needed
+ exit_test
+ else
+ # Check for a SSL_ERROR_SSL error code
+ content_check "SSL_ERROR_SSL"
+ content_check "OpenSSL Error Stack:"
+ fi
+fi
+
+exit_test
diff --git a/tests/sndrcv_tls_ossl_serveranon_gtls_clientanon.sh b/tests/sndrcv_tls_ossl_serveranon_gtls_clientanon.sh
new file mode 100755
index 0000000..eda6ce5
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_serveranon_gtls_clientanon.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# alorbach, 2019-01-16
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input( type="imtcp" port="'$PORT_RCVR'" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)"
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+)
+
+# Note: no TLS for the listener, this is for tcpflood!
+module( load="../plugins/imtcp/.libs/imtcp")
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+# set up the action
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ StreamDriver="gtls"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="anon"
+ )
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m$NUMMESSAGES -i1
+wait_file_lines
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 $NUMMESSAGES
+exit_test
diff --git a/tests/sndrcv_tls_ossl_serveranon_ossl_clientanon.sh b/tests/sndrcv_tls_ossl_serveranon_ossl_clientanon.sh
new file mode 100755
index 0000000..49bb0e1
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_serveranon_ossl_clientanon.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+# alorbach, 2019-01-16
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input( type="imtcp" port="'$PORT_RCVR'" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)"
+add_conf '
+# Note: no TLS for the listener, this is for tcpflood!
+module( load="../plugins/imtcp/.libs/imtcp")
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+# set up the action
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ StreamDriver="ossl"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="anon"
+ )
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m$NUMMESSAGES -i1
+wait_file_lines
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 $NUMMESSAGES
+exit_test
diff --git a/tests/sndrcv_tls_ossl_servercert_gtls_clientanon.sh b/tests/sndrcv_tls_ossl_servercert_gtls_clientanon.sh
new file mode 100755
index 0000000..c9aa2cf
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_servercert_gtls_clientanon.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# alorbach, 2019-01-16
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input( type="imtcp" port="'$PORT_RCVR'" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)"
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+)
+
+# Note: no TLS for the listener, this is for tcpflood!
+module( load="../plugins/imtcp/.libs/imtcp")
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+# set up the action
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ StreamDriver="gtls"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="x509/certvalid"
+ )
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m$NUMMESSAGES -i1
+wait_file_lines
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 $NUMMESSAGES
+exit_test
diff --git a/tests/sndrcv_tls_ossl_servercert_ossl_clientanon.sh b/tests/sndrcv_tls_ossl_servercert_ossl_clientanon.sh
new file mode 100755
index 0000000..66bf0f9
--- /dev/null
+++ b/tests/sndrcv_tls_ossl_servercert_ossl_clientanon.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+# alorbach, 2019-01-16
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=1000
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'"
+)
+
+module( load="../plugins/imtcp/.libs/imtcp"
+ StreamDriver.Name="ossl"
+ StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" )
+# then SENDER sends to this port (not tcpflood!)
+input( type="imtcp" port="'$PORT_RCVR'" )
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)"
+add_conf '
+global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'"
+)
+
+# Note: no TLS for the listener, this is for tcpflood!
+module( load="../plugins/imtcp/.libs/imtcp")
+input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" )
+
+# set up the action
+action( type="omfwd"
+ protocol="tcp"
+ target="127.0.0.1"
+ port="'$PORT_RCVR'"
+ StreamDriver="ossl"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="x509/certvalid"
+ )
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m$NUMMESSAGES -i1
+wait_file_lines
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 $NUMMESSAGES
+exit_test
diff --git a/tests/sndrcv_tls_priorityString.sh b/tests/sndrcv_tls_priorityString.sh
new file mode 100755
index 0000000..2817bf0
--- /dev/null
+++ b/tests/sndrcv_tls_priorityString.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+# Pascal Withopf, 2017-07-25
+# testing sending and receiving via TLS with anon auth
+# NOTE: When this test fails, it could be due to the priorityString being outdated!
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=2500
+# uncomment for debugging support:
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+# start up the instances
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+# certificates
+global(
+ defaultNetstreamDriverCAFile="'$srcdir'/testsuites/x.509/ca.pem"
+ defaultNetstreamDriverCertFile="'$srcdir'/testsuites/x.509/client-cert.pem"
+ defaultNetstreamDriverKeyFile="'$srcdir'/testsuites/x.509/client-key.pem"
+ defaultNetstreamDriver="gtls"
+)
+module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1"
+ StreamDriver.AuthMode="anon" gnutlspriorityString="NORMAL:-MD5")
+input(type="imtcp" port="'$PORT_RCVR'")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum" then {
+ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'")
+}
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)" # TODO: move to diag.sh
+add_conf '
+#certificates
+global(
+ defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'"
+ defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'"
+ defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'"
+ defaultNetstreamDriver="gtls"
+)
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="omfwd" Target="127.0.0.1" port="'$PORT_RCVR'" Protocol="tcp" streamdriver="gtls"
+ StreamDriverAuthMode="anon" StreamDriverMode="1"
+ gnutlsprioritystring="NORMAL:-MD5")
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m$NUMMESSAGES -i1
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+
+wait_file_lines
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check 1 $NUMMESSAGES
+exit_test
diff --git a/tests/sndrcv_udp.sh b/tests/sndrcv_udp.sh
new file mode 100755
index 0000000..39fa680
--- /dev/null
+++ b/tests/sndrcv_udp.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+# This runs sends and receives messages via UDP to the standard
+# ports. Note that with UDP we can always have message loss. While this is
+# less likely in a local environment, we strongly limit the amount of data
+# we send in the hope to not lose any messages. However, failure of this
+# test does not necessarily mean that the code is wrong (but it is very likely!)
+# added 2009-11-11 by Rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+echo ===============================================================================
+echo \[sndrcv_udp.sh\]: testing sending and receiving via udp
+if [ "$EUID" -ne 0 ]; then
+ exit 77 # Not root, skip this test
+fi
+export TCPFLOOD_EXTRA_OPTS="-b1 -W1"
+
+# uncomment for debugging support:
+. ${srcdir:=.}/diag.sh init
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+$ModLoad ../plugins/imudp/.libs/imudp
+# then SENDER sends to this port (not tcpflood!)
+$UDPServerRun '$PORT_RCVR'
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)" # TODO: move to diag.sh
+add_conf '
+$ModLoad ../plugins/imtcp/.libs/imtcp
+# this listener is for message generation by the test framework!
+$InputTCPServerRun '$TCPFLOOD_PORT'
+
+*.* @127.0.0.1:'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m50 -i1
+sleep 5 # make sure all data is received in input buffers
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# do the final check
+seq_check 1 50
+
+unset PORT_RCVR # TODO: move to exit_test()?
+exit_test
diff --git a/tests/sndrcv_udp_nonstdpt.sh b/tests/sndrcv_udp_nonstdpt.sh
new file mode 100755
index 0000000..c792a22
--- /dev/null
+++ b/tests/sndrcv_udp_nonstdpt.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# This runs sends and receives messages via UDP to the non-standard port 2514
+# Note that with UDP we can always have message loss. While this is
+# less likely in a local environment, we strongly limit the amount of data
+# we send in the hope to not lose any messages. However, failure of this
+# test does not necessarily mean that the code is wrong (but it is very likely!)
+# added 2009-11-11 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export TCPFLOOD_EXTRA_OPTS="-b1 -W1"
+export NUMMESSAGES=50
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+add_conf '
+$ModLoad ../plugins/imudp/.libs/imudp
+# then SENDER sends to this port (not tcpflood!)
+$UDPServerRun '$TCPFLOOD_PORT'
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names!
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+export PORT_RCVR="$TCPFLOOD_PORT"
+
+#valgrind="valgrind"
+generate_conf 2
+add_conf '
+*.* @127.0.0.1:'$PORT_RCVR'
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+injectmsg2
+
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+seq_check
+exit_test
diff --git a/tests/sndrcv_udp_nonstdpt_v6.sh b/tests/sndrcv_udp_nonstdpt_v6.sh
new file mode 100755
index 0000000..948d9f8
--- /dev/null
+++ b/tests/sndrcv_udp_nonstdpt_v6.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# added 2014-11-05 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[sndrcv_udp_nonstdpt_v6.sh\]: testing sending and receiving via udp
+
+# uncomment for debugging support:
+. ${srcdir:=.}/diag.sh init
+# start up the instances
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
+export RSYSLOG_DEBUGLOG="log"
+generate_conf
+export PORT_RCVR="$(get_free_port)"
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+# then SENDER sends to this port (not tcpflood!)
+input(type="imudp" address="127.0.0.1" port=`echo $PORT_RCVR`)
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+export RSYSLOG_DEBUGLOG="log2"
+#valgrind="valgrind"
+generate_conf 2
+export TCPFLOOD_PORT="$(get_free_port)" # TODO: move to diag.sh
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+# this listener is for message generation by the test framework!
+input(type="imtcp" port=`echo $TCPFLOOD_PORT`)
+
+action(type="omfwd"
+ target="127.0.0.1" port=`echo $PORT_RCVR`
+ protocol="udp" udp.sendDelay="1")
+' 2
+startup 2
+
+# now inject the messages into instance 2. It will connect to instance 1,
+# and that instance will record the data.
+tcpflood -m500 -i1
+sleep 5 # make sure all data is received in input buffers
+# shut down sender when everything is sent, receiver continues to run concurrently
+shutdown_when_empty 2
+wait_shutdown 2
+# now it is time to stop the receiver as well
+shutdown_when_empty
+wait_shutdown
+
+# do the final check
+seq_check 1 500
+
+unset PORT_RCVR # TODO: move to exit_test()?
+exit_test
diff --git a/tests/snmptrapreceiver.py b/tests/snmptrapreceiver.py
new file mode 100755
index 0000000..643a8c4
--- /dev/null
+++ b/tests/snmptrapreceiver.py
@@ -0,0 +1,104 @@
+# call this via "python[3] script name"
+import sys
+from pysnmp.entity import engine, config
+from pysnmp.carrier.asyncore.dgram import udp
+from pysnmp.entity.rfc3413 import ntfrcv
+from pysnmp.smi import builder, view, compiler, rfc1902
+from pyasn1.type.univ import OctetString
+
+# Global variables
+snmpport = 10162
+snmpip = "127.0.0.1"
+szOutputfile = "snmp.out"
+szSnmpLogfile = "snmp_server.log"
+
+# For vrebose output
+bDebug = False
+
+# Read command line params
+if len(sys.argv) > 1:
+ snmpport = int(sys.argv[1])
+if len(sys.argv) > 2:
+ snmpip = sys.argv[2]
+if len(sys.argv) > 3:
+ szOutputfile = sys.argv[3]
+if len(sys.argv) > 4:
+ szSnmpLogfile = sys.argv[4]
+
+# Create output files
+outputFile = open(szOutputfile,"w+")
+logFile = open(szSnmpLogfile,"a+")
+
+# Assemble MIB viewer
+mibBuilder = builder.MibBuilder()
+compiler.addMibCompiler(mibBuilder, sources=['file:///usr/share/snmp/mibs', 'file:///var/lib/snmp/mibs', '/usr/local/share/snmp/mibs/'])
+mibViewController = view.MibViewController(mibBuilder)
+# Pre-load MIB modules we expect to work with
+try:
+ mibBuilder.loadModules('SNMPv2-MIB', 'SNMP-COMMUNITY-MIB', 'SYSLOG-MSG-MIB')
+except Exception:
+ print("Failed loading MIBs")
+
+# Create SNMP engine with autogenernated engineID and pre-bound to socket transport dispatcher
+snmpEngine = engine.SnmpEngine()
+
+# Transport setup
+# UDP over IPv4, add listening interface/port
+config.addTransport(
+ snmpEngine,
+ udp.domainName + (1,),
+ udp.UdpTransport().openServerMode((snmpip, snmpport))
+)
+
+# SNMPv1/2c setup
+# SecurityName <-> CommunityName mapping
+config.addV1System(snmpEngine, 'my-area', 'public')
+
+print("Started SNMP Trap Receiver: %s, %s, Output: %s" % (snmpport, snmpip, szOutputfile))
+logFile.write("Started SNMP Trap Receiver: %s, %s, Output: %s" % (snmpport, snmpip, szOutputfile))
+logFile.flush()
+
+# Callback function for receiving notifications
+# noinspection PyUnusedLocal,PyUnusedLocal,PyUnusedLocal
+def cbReceiverSnmp(snmpEngine, stateReference, contextEngineId, contextName, varBinds, cbCtx):
+ transportDomain, transportAddress = snmpEngine.msgAndPduDsp.getTransportInfo(stateReference)
+ if (bDebug):
+ szDebug = str("Notification From: %s, Domain: %s, SNMP Engine: %s, Context: %s" %
+ (transportAddress, transportDomain, contextEngineId.prettyPrint(), contextName.prettyPrint()))
+ print(szDebug)
+ logFile.write(szDebug)
+ logFile.flush()
+
+ # Create output String
+ szOut = "Trap Source{}, Trap OID {}".format(transportAddress, transportDomain)
+
+ varBinds = [rfc1902.ObjectType(rfc1902.ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController) for x in varBinds]
+
+ for name, val in varBinds:
+ # Append to output String
+ szOut = szOut + ", Oid: {}, Value: {}".format(name.prettyPrint(), val.prettyPrint())
+
+ if isinstance(val, OctetString):
+ if (name.prettyPrint() != "SNMP-COMMUNITY-MIB::snmpTrapAddress.0"):
+ szOctets = val.asOctets()#.rstrip('\r').rstrip('\n')
+ szOut = szOut + ", Octets: {}".format(szOctets)
+ if (bDebug):
+ print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
+ outputFile.write(szOut)
+ if "\n" not in szOut:
+ outputFile.write("\n")
+ outputFile.flush()
+
+
+# Register SNMP Application at the SNMP engine
+ntfrcv.NotificationReceiver(snmpEngine, cbReceiverSnmp)
+
+# this job would never finish
+snmpEngine.transportDispatcher.jobStarted(1)
+
+# Run I/O dispatcher which would receive queries and send confirmations
+try:
+ snmpEngine.transportDispatcher.runDispatcher()
+except:
+ snmpEngine.transportDispatcher.closeDispatcher()
+ raise
diff --git a/tests/sparse_array_lookup_table-vg.sh b/tests/sparse_array_lookup_table-vg.sh
new file mode 100755
index 0000000..37519d6
--- /dev/null
+++ b/tests/sparse_array_lookup_table-vg.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# added 2015-10-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/sparse_array_lookup_table.sh
diff --git a/tests/sparse_array_lookup_table.sh b/tests/sparse_array_lookup_table.sh
new file mode 100755
index 0000000..bb23959
--- /dev/null
+++ b/tests/sparse_array_lookup_table.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+# test for sparse-array lookup-table and HUP based reloading of it
+# added 2015-10-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate_array.lkp_tbl")
+
+template(name="outfmt" type="string" string="%msg% %$.lkp%\n")
+
+set $.num = field($msg, 58, 2);
+
+set $.lkp = lookup("xlate", $.num);
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+cp -f $srcdir/testsuites/xlate_sparse_array.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl
+startup
+injectmsg 0 1
+wait_queueempty
+assert_content_missing "foo"
+injectmsg 0 5
+wait_queueempty
+content_check "msgnum:00000001: foo_old"
+content_check "msgnum:00000002: foo_old"
+content_check "msgnum:00000003: bar_old"
+content_check "msgnum:00000004: bar_old"
+assert_content_missing "baz"
+cp -f $srcdir/testsuites/xlate_sparse_array_more.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 6
+wait_queueempty
+content_check "msgnum:00000000: foo_new"
+content_check "msgnum:00000001: foo_new"
+content_check "msgnum:00000002: bar_new"
+content_check "msgnum:00000003: bar_new"
+content_check "msgnum:00000004: baz"
+content_check "msgnum:00000005: baz"
+cp -f $srcdir/testsuites/xlate_sparse_array_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl
+issue_HUP
+await_lookup_table_reload
+injectmsg 0 15
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check "msgnum:00000000: quux"
+content_check "msgnum:00000001: quux"
+content_check "msgnum:00000002: foo_latest"
+content_check "msgnum:00000003: baz_latest"
+content_check "msgnum:00000004: foo_latest"
+content_check "msgnum:00000005: foo_latest"
+content_check "msgnum:00000006: foo_latest"
+content_check "msgnum:00000007: foo_latest"
+content_check "msgnum:00000008: baz_latest"
+content_check "msgnum:00000009: baz_latest"
+content_check "msgnum:00000010: baz_latest"
+content_check "msgnum:00000011: baz_latest"
+content_check "msgnum:00000012: foo_latest"
+content_check "msgnum:00000013: foo_latest"
+content_check "msgnum:00000014: foo_latest"
+exit_test
diff --git a/tests/stats-cee-vg.sh b/tests/stats-cee-vg.sh
new file mode 100755
index 0000000..2807da5
--- /dev/null
+++ b/tests/stats-cee-vg.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# added 2016-03-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[stats-cee-vg.sh\]: test for verifying stats are reported correctly cee format with valgrind
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="cee")
+
+if ($msg == "this condition will never match") then {
+ action(name="an_action_that_is_never_called" type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup_vg
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+wait_queueempty
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+custom_content_check '@cee: { "name": "an_action_that_is_never_called", "origin": "core.action", "processed": 0, "failed": 0, "suspended": 0, "suspended.duration": 0, "resumed": 0 }' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/stats-cee.sh b/tests/stats-cee.sh
new file mode 100755
index 0000000..6fd2b65
--- /dev/null
+++ b/tests/stats-cee.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2016-03-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[stats-cee.sh\]: test for verifying stats are reported correctly cee format
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="cee")
+
+if ($msg == "this condition will never match") then {
+ action(name="an_action_that_is_never_called" type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+wait_queueempty
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+custom_content_check '@cee: { "name": "an_action_that_is_never_called", "origin": "core.action", "processed": 0, "failed": 0, "suspended": 0, "suspended.duration": 0, "resumed": 0 }' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/stats-json-es.sh b/tests/stats-json-es.sh
new file mode 100755
index 0000000..7162930
--- /dev/null
+++ b/tests/stats-json-es.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# added 2016-03-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[stats-json-es.sh\]: test for verifying stats are reported correctly json-elasticsearch format
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="json-elasticsearch")
+
+if ($msg == "this condition will never match") then {
+ action(name="an_action_that_is_never_called" type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+wait_queueempty
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+custom_content_check '{ "name": "an_action_that_is_never_called", "origin": "core.action", "processed": 0, "failed": 0, "suspended": 0, "suspended!duration": 0, "resumed": 0 }' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing '@cee' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/stats-json-vg.sh b/tests/stats-json-vg.sh
new file mode 100755
index 0000000..73177d5
--- /dev/null
+++ b/tests/stats-json-vg.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# added 2016-03-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[stats-json-vg.sh\]: test for verifying stats are reported correctly json format with valgrind
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="json")
+
+if ($msg == "this condition will never match") then {
+ action(name="an_action_that_is_never_called" type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup_vg
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+wait_queueempty
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown_vg
+check_exit_vg
+custom_content_check '{ "name": "an_action_that_is_never_called", "origin": "core.action", "processed": 0, "failed": 0, "suspended": 0, "suspended.duration": 0, "resumed": 0 }' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing '@cee' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/stats-json.sh b/tests/stats-json.sh
new file mode 100755
index 0000000..91298d4
--- /dev/null
+++ b/tests/stats-json.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# added 2016-03-30 by singh.janmejay
+# test for verifying stats are reported correctly json format
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+ruleset(name="stats") {
+ action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log")
+}
+
+module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="json")
+
+if ($msg == "this condition will never match") then {
+ action(name="an_action_that_is_never_called" type="omfile" file=`echo $RSYSLOG_OUT_LOG`)
+}
+'
+startup
+injectmsg_file $srcdir/testsuites/dynstats_input_1
+wait_queueempty
+wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+custom_content_check '{ "name": "an_action_that_is_never_called", "origin": "core.action", "processed": 0, "failed": 0, "suspended": 0, "suspended.duration": 0, "resumed": 0 }' "${RSYSLOG_DYNNAME}.out.stats.log"
+custom_assert_content_missing '@cee' "${RSYSLOG_DYNNAME}.out.stats.log"
+exit_test
diff --git a/tests/stop-localvar.sh b/tests/stop-localvar.sh
new file mode 100755
index 0000000..f5fcb99
--- /dev/null
+++ b/tests/stop-localvar.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Test for "stop" statement
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[stop-localvar.sh\]: testing stop statement together with local variables
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$.nbr%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+if $msg contains "msgnum:" then {
+ set $.nbr = field($msg, 58, 2);
+ if cnum($.nbr) < 100 then
+ stop
+ /* check is intentionally more complex than needed! */
+ else if not (cnum($.nbr) > 999) then {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+ }
+}
+'
+startup
+sleep 1
+tcpflood -m2000 -i1
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 100 999
+exit_test
diff --git a/tests/stop-msgvar.sh b/tests/stop-msgvar.sh
new file mode 100755
index 0000000..9a1c09f
--- /dev/null
+++ b/tests/stop-msgvar.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Test for "stop" statement
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[stop-msgvar.sh\]: testing stop statement together with message variables
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%$!nbr%\n")
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+if $msg contains "msgnum:" then {
+ set $!nbr = field($msg, 58, 2);
+ if cnum($!nbr) < 100 then
+ stop
+ /* check is intentionally more complex than needed! */
+ else if not (cnum($!nbr) > 999) then {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+ }
+}
+'
+startup
+sleep 1
+tcpflood -m2000 -i1
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 100 999
+exit_test
diff --git a/tests/stop.sh b/tests/stop.sh
new file mode 100755
index 0000000..22f5655
--- /dev/null
+++ b/tests/stop.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# Test for "stop" statement
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[stop.sh\]: testing stop statement
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+if $msg contains "00000001" then
+ stop
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+sleep 1
+tcpflood -m10 -i1
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 2 10
+exit_test
diff --git a/tests/stop_when_array_has_element.sh b/tests/stop_when_array_has_element.sh
new file mode 100755
index 0000000..030013e
--- /dev/null
+++ b/tests/stop_when_array_has_element.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# added 2015-05-22 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+echo ===============================================================================
+echo \[stop_when_array_has_element.sh\]: loop detecting presence of an element and stopping ruleset execution
+. ${srcdir:=.}/diag.sh init stop_when_array_has_element.sh
+generate_conf
+add_conf '
+template(name="foo" type="string" string="%$!foo%\n")
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+action(type="mmjsonparse")
+
+foreach ($.quux in $!foo) do {
+ if ($.quux == "xyz0") then stop
+}
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="foo")
+'
+startup
+tcpflood -m 1 -I $srcdir/testsuites/stop_when_array_has_elem_input
+echo doing shutdown
+shutdown_when_empty
+echo wait on shutdown
+wait_shutdown
+content_check '"abc0"'
+content_check '"abc2"'
+assert_content_missing 'xyz0'
+exit_test
diff --git a/tests/suspend-omfwd-via-file.sh b/tests/suspend-omfwd-via-file.sh
new file mode 100755
index 0000000..1df6f32
--- /dev/null
+++ b/tests/suspend-omfwd-via-file.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# This tests the action suspension via a file
+# This file is part of the rsyslog project, released under ASL 2.0
+# Written 2019-07-10 by Rainer Gerhards
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=10000
+#export NUMMESSAGES=100 #00
+generate_conf
+add_conf '
+/* Filter out busy debug output, comment out if needed */
+global( debug.whitelist="on"
+ debug.files=["ruleset.c", "../action.c", "omfwd.c"]
+)
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+:msg, contains, "msgnum:" {
+ action(name="forwarder" type="omfwd" template="outfmt"
+ target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="tcp"
+ action.externalstate.file="'$RSYSLOG_DYNNAME'.STATE"
+ action.resumeRetryCount="-1" action.resumeinterval="1")
+}
+'
+
+./minitcpsrv -t127.0.0.1 -p$TCPFLOOD_PORT -f $RSYSLOG_OUT_LOG &
+BGPROCESS=$!
+echo background minitcpsrv process id is $BGPROCESS
+
+startup
+injectmsg 0 5000
+#injectmsg 0 5
+
+printf '\n%s %s\n' "$(tb_timestamp)" \
+ 'checking that action becomes suspended via external state file'
+printf "%s" "SUSPENDED" > $RSYSLOG_DYNNAME.STATE
+./msleep 2000 # ensure ResumeInterval expired (NOT sensitive to slow machines --> absolute time!)
+injectmsg 5000 1000
+#injectmsg 5 5
+
+printf '\n%s %s\n' "$(tb_timestamp)" \
+ 'checking that action becomes resumed again via external state file'
+./msleep 2000 # ensure ResumeInterval expired (NOT sensitive to slow machines --> absolute time!)
+printf "%s" "READY" > $RSYSLOG_DYNNAME.STATE
+
+injectmsg 6000 4000
+#export QUEUE_EMPTY_CHECK_FUNC=check_q_empty_log2
+wait_queueempty
+seq_check
+shutdown_when_empty
+wait_shutdown
+exit_test
diff --git a/tests/suspend-via-file.sh b/tests/suspend-via-file.sh
new file mode 100755
index 0000000..e2cefa7
--- /dev/null
+++ b/tests/suspend-via-file.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+# This tests the action suspension via a file; we use a SUSPENDED string
+# with trailing whitespace in this test.
+# This file is part of the rsyslog project, released under ASL 2.0
+# Written 2018-08-13 by Rainer Gerhards
+. ${srcdir:=.}/diag.sh init
+check_q_empty_log1() {
+ echo "###### in check1"
+ wait_seq_check 2500 4999
+}
+check_q_empty_log2() {
+ echo "###### in check2"
+ wait_seq_check 0 $LOG2_EXPECTED_LASTNUM
+}
+generate_conf
+add_conf '
+/* Filter out busy debug output, comment out if needed */
+global( debug.whitelist="on"
+ debug.files=["ruleset.c", "../action.c", "omfwd.c"]
+)
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+:msg, contains, "msgnum:" {
+ action(name="primary" type="omfile" file="'$RSYSLOG2_OUT_LOG'" template="outfmt"
+ action.externalstate.file="'$RSYSLOG_DYNNAME'.STATE" action.resumeinterval="1")
+ action(name="failover" type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt"
+ action.execOnlyWhenPreviousIsSuspended="on")
+}
+'
+startup
+
+printf '\n%s %s\n' "$(tb_timestamp)" \
+ 'STEP 1: checking that action is active w/o external state file'
+injectmsg 0 2500
+export SEQ_CHECK_FILE="$RSYSLOG2_OUT_LOG"
+export LOG2_EXPECTED_LASTNUM=2499
+export QUEUE_EMPTY_CHECK_FUNC=check_q_empty_log2
+wait_queueempty
+seq_check 0 $LOG2_EXPECTED_LASTNUM # full correctness check
+
+
+printf '\n%s %s\n' "$(tb_timestamp)" \
+ 'STEP 2: checking that action becomes suspended via external state file'
+printf 'SUSPENDED \n' > $RSYSLOG_DYNNAME.STATE
+injectmsg 2500 2500
+export SEQ_CHECK_FILE="$RSYSLOG_OUT_LOG"
+export QUEUE_EMPTY_CHECK_FUNC=check_q_empty_log1
+wait_queueempty
+seq_check 2500 4999 # full correctness check
+
+printf '\n%s %s\n' "$(tb_timestamp)" \
+ 'STEP 3: checking that action becomes resumed again via external state file'
+printf "%s" "READY" > $RSYSLOG_DYNNAME.STATE
+./msleep 2000 # ensure ResumeInterval expired (NOT sensitive to slow machines --> absolute time!)
+injectmsg 2500 2500
+export SEQ_CHECK_FILE="$RSYSLOG2_OUT_LOG"
+export LOG2_EXPECTED_LASTNUM=4999
+export QUEUE_EMPTY_CHECK_FUNC=check_q_empty_log2
+shutdown_when_empty
+wait_shutdown
+
+# final checks
+export SEQ_CHECK_FILE="$RSYSLOG_OUT_LOG"
+seq_check 2500 4999
+export SEQ_CHECK_FILE="$RSYSLOG2_OUT_LOG"
+seq_check 0 4999
+exit_test
diff --git a/tests/syslog_caller.c b/tests/syslog_caller.c
new file mode 100644
index 0000000..1a0b04f
--- /dev/null
+++ b/tests/syslog_caller.c
@@ -0,0 +1,151 @@
+/* A testing tool that just emits a number of
+ * messages to the system log socket.
+ *
+ * Options
+ *
+ * -s severity (0..7 accoding to syslog spec, r "rolling", default 6)
+ * -m number of messages to generate (default 500)
+ * -C liblognorm-stdlog channel description
+ * -f message format to use
+ *
+ * Part of the testbench for rsyslog.
+ *
+ * Copyright 2010-2018 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * -or-
+ * see COPYING.ASL20 in the source distribution
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if defined(_AIX)
+ #include <unistd.h>
+#else
+ #include <getopt.h>
+#endif
+#include <errno.h>
+#include <string.h>
+#include <syslog.h>
+#ifdef HAVE_LIBLOGGING_STDLOG
+#include <liblogging/stdlog.h>
+#endif
+
+static enum { FMT_NATIVE, FMT_SYSLOG_INJECT_L, FMT_SYSLOG_INJECT_C
+ } fmt = FMT_NATIVE;
+
+static void usage(void)
+{
+ fprintf(stderr, "usage: syslog_caller num-messages\n");
+ exit(1);
+}
+
+
+#ifdef HAVE_LIBLOGGING_STDLOG
+/* buffer must be large "enough" [4K?] */
+static void
+genMsg(char *buf, const int sev, const int iRun)
+{
+ switch(fmt) {
+ case FMT_NATIVE:
+ sprintf(buf, "test message nbr %d, severity=%d", iRun, sev);
+ break;
+ case FMT_SYSLOG_INJECT_L:
+ sprintf(buf, "test\n");
+ break;
+ case FMT_SYSLOG_INJECT_C:
+ sprintf(buf, "test 1\t2");
+ break;
+ }
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+ int i;
+ int opt;
+ int bRollingSev = 0;
+ int sev = 6;
+ int msgs = 500;
+#ifdef HAVE_LIBLOGGING_STDLOG
+ stdlog_channel_t logchan = NULL;
+ const char *chandesc = "syslog:";
+ char msgbuf[4096];
+#endif
+
+#ifdef HAVE_LIBLOGGING_STDLOG
+ stdlog_init(STDLOG_USE_DFLT_OPTS);
+ while((opt = getopt(argc, argv, "m:s:C:f:")) != -1) {
+#else
+ while((opt = getopt(argc, argv, "m:s:")) != -1) {
+#endif
+ switch (opt) {
+ case 's': if(*optarg == 'r') {
+ bRollingSev = 1;
+ sev = 0;
+ } else
+#ifdef HAVE_LIBLOGGING_STDLOG
+ sev = atoi(optarg) % 8;
+#else
+ sev = atoi(optarg);
+#endif
+ break;
+ case 'm': msgs = atoi(optarg);
+ break;
+#ifdef HAVE_LIBLOGGING_STDLOG
+ case 'C': chandesc = optarg;
+ break;
+ case 'f': if(!strcmp(optarg, "syslog_inject-l"))
+ fmt = FMT_SYSLOG_INJECT_L;
+ else if(!strcmp(optarg, "syslog_inject-c"))
+ fmt = FMT_SYSLOG_INJECT_C;
+ else
+ usage();
+ break;
+#endif
+ default: usage();
+#ifdef HAVE_LIBLOGGING_STDLOG
+ exit(1);
+#endif
+ break;
+ }
+ }
+
+#ifdef HAVE_LIBLOGGING_STDLOG
+ if((logchan = stdlog_open(argv[0], 0, STDLOG_LOCAL1, chandesc)) == NULL) {
+ fprintf(stderr, "error opening logchannel '%s': %s\n",
+ chandesc, strerror(errno));
+ exit(1);
+ }
+#endif
+ for(i = 0 ; i < msgs ; ++i) {
+#ifdef HAVE_LIBLOGGING_STDLOG
+ genMsg(msgbuf, sev, i);
+ if(stdlog_log(logchan, sev, "%s", msgbuf) != 0) {
+ perror("error writing log record");
+ exit(1);
+ }
+#else
+ syslog(sev % 8, "test message nbr %d, severity=%d", i, sev % 8);
+#endif
+ if(bRollingSev)
+#ifdef HAVE_LIBLOGGING_STDLOG
+ sev = (sev + 1) % 8;
+#else
+ sev++;
+#endif
+ }
+ return(0);
+}
diff --git a/tests/tabescape_dflt-udp.sh b/tests/tabescape_dflt-udp.sh
new file mode 100755
index 0000000..481acba
--- /dev/null
+++ b/tests/tabescape_dflt-udp.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 test: before HT after HT (do NOT remove TAB!)\""
+shutdown_when_empty
+wait_shutdown
+
+echo ' before HT#011after HT (do NOT remove TAB!)' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/tabescape_dflt.sh b/tests/tabescape_dflt.sh
new file mode 100755
index 0000000..63b925e
--- /dev/null
+++ b/tests/tabescape_dflt.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 test: before HT after HT (do NOT remove TAB!)\""
+shutdown_when_empty
+wait_shutdown
+
+echo ' before HT#011after HT (do NOT remove TAB!)' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/tabescape_off-udp.sh b/tests/tabescape_off-udp.sh
new file mode 100755
index 0000000..8374844
--- /dev/null
+++ b/tests/tabescape_off-udp.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imudp/.libs/imudp")
+input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1")
+
+$ErrorMessagesToStderr off
+$EscapeControlCharacterTab off
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 test: before HT after HT (do NOT remove TAB!)\""
+shutdown_when_empty
+wait_shutdown
+
+echo ' before HT after HT (do NOT remove TAB!)' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/tabescape_off.sh b/tests/tabescape_off.sh
new file mode 100755
index 0000000..3aa9bf0
--- /dev/null
+++ b/tests/tabescape_off.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(parser.EscapeControlCharacterTab="off")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+$ErrorMessagesToStderr off
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 test: before HT after HT (do NOT remove TAB!)\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED=' before HT after HT (do NOT remove TAB!)'
+cmp_exact
+
+exit_test
diff --git a/tests/tabescape_on.sh b/tests/tabescape_on.sh
new file mode 100755
index 0000000..ad41a95
--- /dev/null
+++ b/tests/tabescape_on.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# add 2018-06-29 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+global(parser.EscapeControlCharacterTab="on")
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1")
+
+$ErrorMessagesToStderr off
+
+template(name="outfmt" type="string" string="%msg%\n")
+
+ruleset(name="ruleset1") {
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+}
+
+'
+startup
+tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 test: before HT after HT (do NOT remove TAB!)\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED=' before HT#011after HT (do NOT remove TAB!)'
+cmp_exact
+
+exit_test
diff --git a/tests/tcp-msgreduc-vg.sh b/tests/tcp-msgreduc-vg.sh
new file mode 100755
index 0000000..c68fdb2
--- /dev/null
+++ b/tests/tcp-msgreduc-vg.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# check if valgrind violations occur. Correct output is not checked.
+# added 2011-03-01 by Rgerhards
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+# exit 77
+fi
+
+export NUMMESSAGES=4
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+$RepeatedMsgReduction on
+
+$template outfmt,"%msg:F,58:2%\n"
+*.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+tcpflood -t 127.0.0.1 -m 4 -r -M "\"<133>2011-03-01T11:22:12Z host tag msgh ...\""
+tcpflood -t 127.0.0.1 -m 1 -r -M "\"<133>2011-03-01T11:22:12Z host tag msgh ...x\""
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+exit_test
diff --git a/tests/tcp_forwarding_dflt_tpl.sh b/tests/tcp_forwarding_dflt_tpl.sh
new file mode 100755
index 0000000..0dc7070
--- /dev/null
+++ b/tests/tcp_forwarding_dflt_tpl.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# This test tests tcp forwarding with assigned default template.
+# added 2015-05-30 by rgerhards. Released under ASL 2.0
+
+# create the pipe and start a background process that copies data from
+# it to the "regular" work file
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MainMsgQueueTimeoutShutdown 10000
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+#this is what we want to test: setting the default template
+module(load="builtin:omfwd" template="outfmt")
+
+if $msg contains "msgnum:" then
+ action(type="omfwd" target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="tcp")
+'
+./minitcpsrv -t127.0.0.1 -p$TCPFLOOD_PORT -f $RSYSLOG_OUT_LOG &
+BGPROCESS=$!
+echo background minitcpsrv process id is $BGPROCESS
+
+# now do the usual run
+startup
+# 10000 messages should be enough
+injectmsg 0 10000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+# note: minitcpsrv shuts down automatically if the connection is closed!
+# (we still leave the code here in in case we need it later)
+#echo shutting down minitcpsrv...
+#kill $BGPROCESS
+#wait $BGPROCESS
+#echo background process has terminated, continue test...
+
+# and continue the usual checks
+seq_check 0 9999
+exit_test
diff --git a/tests/tcp_forwarding_ns_tpl.sh b/tests/tcp_forwarding_ns_tpl.sh
new file mode 100755
index 0000000..89a45e3
--- /dev/null
+++ b/tests/tcp_forwarding_ns_tpl.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# This test tests tcp forwarding in a network namespace with assigned template.
+# To do so, a simple tcp listener service is started in a network namespace.
+# Released under GNU GPLv3+
+echo ===============================================================================
+echo \[tcp_forwarding_ns_tpl.sh\]: test for tcp forwarding in a network namespace with assigned template
+echo This test must be run as root [network namespace creation/change required]
+if [ "$EUID" -ne 0 ]; then
+ exit 77 # Not root, skip this test
+fi
+
+# create the pipe and start a background process that copies data from
+# it to the "regular" work file
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MainMsgQueueTimeoutShutdown 10000
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum:" then
+ action(type="omfwd" template="outfmt"
+ target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="tcp" networknamespace="rsyslog_test_ns")
+'
+# create network namespace and bring it up
+ip netns add rsyslog_test_ns
+ip netns exec rsyslog_test_ns ip link set dev lo up
+
+# run server in namespace
+ip netns exec rsyslog_test_ns ./minitcpsrv -t127.0.0.1 -p'$TCPFLOOD_PORT' -f $RSYSLOG_OUT_LOG &
+BGPROCESS=$!
+echo background minitcpsrvr process id is $BGPROCESS
+
+# now do the usual run
+startup
+# 10000 messages should be enough
+injectmsg 0 10000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+# note: minitcpsrvr shuts down automatically if the connection is closed!
+# (we still leave the code here in in case we need it later)
+#echo shutting down minitcpsrv...
+#kill $BGPROCESS
+#wait $BGPROCESS
+#echo background process has terminated, continue test...
+
+# remove network namespace
+ip netns delete rsyslog_test_ns
+
+# and continue the usual checks
+seq_check 0 9999
+exit_test
diff --git a/tests/tcp_forwarding_retries.sh b/tests/tcp_forwarding_retries.sh
new file mode 100755
index 0000000..eb7a69b
--- /dev/null
+++ b/tests/tcp_forwarding_retries.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# added 2016-06-21 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+messages=20000 # how many messages to inject?
+# Note: we need to inject a somewhat larger number of messages in order
+# to ensure that we receive some messages in the actual output file,
+# as batching can (validly) cause a larger loss in the non-writable
+# file
+
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+:msg, contains, "msgnum:" {
+ action(type="omfwd"
+ target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="TCP"
+ action.resumeRetryCount="10"
+ template="outfmt")
+}
+'
+
+# we start a small receiver process
+./minitcpsrv -t127.0.0.1 -p$TCPFLOOD_PORT -f $RSYSLOG_OUT_LOG -s4 &
+BGPROCESS=$!
+echo background minitcpsrvr process id is $BGPROCESS
+
+startup
+injectmsg 0 $messages
+shutdown_when_empty
+wait_shutdown
+
+# note: minitcpsrvr shuts down automatically if the connection is closed, but
+# we still try to kill it in case the test did not connect to it! Note that we
+# do not need an extra wait, as the rsyslog shutdown process should have taken
+# far long enough.
+echo waiting on background process
+kill $BGPROCESS &> /dev/null
+wait $BGPROCESS
+
+seq_check 0 $(($messages-1))
+exit_test
diff --git a/tests/tcp_forwarding_tpl.sh b/tests/tcp_forwarding_tpl.sh
new file mode 100755
index 0000000..3eba8e0
--- /dev/null
+++ b/tests/tcp_forwarding_tpl.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# This test tests tcp forwarding with assigned template. To do so, a simple
+# tcp listener service is started.
+# added 2012-10-30 by Rgerhards. Released under ASL 2.0
+
+# create the pipe and start a background process that copies data from
+# it to the "regular" work file
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MainMsgQueueTimeoutShutdown 10000
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+
+if $msg contains "msgnum:" then
+ action(type="omfwd" template="outfmt"
+ target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="tcp")
+'
+./minitcpsrv -t127.0.0.1 -p$TCPFLOOD_PORT -f $RSYSLOG_OUT_LOG &
+BGPROCESS=$!
+echo background minitcpsrvr process id is $BGPROCESS
+
+# now do the usual run
+startup
+# 10000 messages should be enough
+injectmsg 0 10000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+
+# note: minitcpsrvr shuts down automatically if the connection is closed!
+# (we still leave the code here in in case we need it later)
+#echo shutting down minitcpsrv...
+#kill $BGPROCESS
+#wait $BGPROCESS
+#echo background process has terminated, continue test...
+
+# and continue the usual checks
+seq_check 0 9999
+exit_test
diff --git a/tests/tcpflood.c b/tests/tcpflood.c
new file mode 100644
index 0000000..bd8edaf
--- /dev/null
+++ b/tests/tcpflood.c
@@ -0,0 +1,2108 @@
+/* Opens a large number of tcp connections and sends
+ * messages over them. This is used for stress-testing.
+ *
+ * NOTE: the following part is actually the SPEC (or call it man page).
+ * It's not random comments. So if the code behavior does not match what
+ * is written here, it should be considered a bug.
+ *
+ * Params
+ * -t target address (default 127.0.0.1)
+ * -p target port(s) (default 13514), multiple via port1:port2:port3...
+ * -n number of target ports (all target ports must be given in -p!)
+ * Note -c must also be set to at LEAST the number of -n!
+ * -c number of connections (default 1), use negative number
+ * to set a "soft limit": if tcpflood cannot open the
+ * requested number of connections, gracefully degrade to
+ * whatever number could be opened. This is useful in environments
+ * where system config constraints cannot be overriden (e.g.
+ * vservers, non-admin users, ...)
+ * -m number of messages to send (connection is random)
+ * -i initial message number (optional)
+ * -P PRI to be used for generated messages (default is 167).
+ * Specify the plain number without leading zeros
+ * -d amount of extra data to add to message. If present, the
+ * number itself will be added as third field, and the data
+ * bytes as forth. Add -r to randomize the amount of extra
+ * data included in the range 1..(value of -d).
+ * -r randomize amount of extra data added (-d must be > 0)
+ * -s (silent) do not show progress indicator (never done on non-tty)
+ * -f support for testing dynafiles. If given, include a dynafile ID
+ * in the range 0..(f-1) as the SECOND field, shifting all field values
+ * 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
+ * delimiters 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
+ * -R number of times the test shall be run (very useful for gathering performance
+ * data and other repetitive things). Default: 1
+ * -S number of seconds to sleep between different runs (-R) Default: 30
+ * -X generate sTats data records. Default: off
+ * -e encode output in CSV (not yet everywhere supported)
+ * for performance data:
+ * each inidividual line has the runtime of one test
+ * the last line has 0 in field 1, followed by numberRuns,TotalRuntime,
+ * Average,min,max
+ * -T transport to use. Currently supported: "udp", "tcp" (default), "tls" (tcp+tls), relp-plain, relp-tls
+ * Note: UDP supports a single target port, only
+ * -u Set RELP TLS Library to gnutls or openssl
+ * -W wait time between sending batches of messages, in microseconds (Default: 0)
+ * -b number of messages within a batch (default: 100,000,000 millions)
+ * -Y use multiple threads, one per connection (which means 1 if one only connection
+ * is configured!)
+ * -y use RFC5424 style test message
+ * -x CA Cert File for verification (TLS Mode / OpenSSL only)
+ * -z private key file for TLS mode
+ * -Z cert (public key) file for TLS mode
+ * -a Authentication Mode for relp-tls
+ * -A do NOT abort if an error occured during sending messages
+ * -E Permitted Peer for relp-tls
+ * -L loglevel to use for GnuTLS troubleshooting (0-off to 10-all, 0 default)
+ * -j format message in json, parameter is JSON cookie
+ * -O Use octate-count framing
+ * -v verbose output, possibly useful for troubleshooting. Most importantly,
+ * this gives insight into librelp actions (if relp is selected as protocol).
+ * -k Custom Configuration string passwed through the TLS library.
+ * Currently only OpenSSL is supported, possible configuration commands and values can be found here:
+ * https://www.openssl.org/docs/man1.0.2/man3/SSL_CONF_cmd.html
+ * Sample: -k"Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.1"
+ * Works for LIBRELP now as well!
+ *
+ * Part of the testbench for rsyslog.
+ *
+ * Copyright 2009-2019 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 <strings.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#ifdef ENABLE_RELP
+#include <librelp.h>
+#endif
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <errno.h>
+#ifdef ENABLE_GNUTLS
+# include <gnutls/gnutls.h>
+# if GNUTLS_VERSION_NUMBER <= 0x020b00
+# include <gcrypt.h>
+ GCRY_THREAD_OPTION_PTHREAD_IMPL;
+# endif
+#endif
+#ifdef ENABLE_OPENSSL
+ #include <openssl/ssl.h>
+ #include <openssl/x509v3.h>
+ #include <openssl/err.h>
+ #include <openssl/engine.h>
+
+ /* OpenSSL API differences */
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ #define RSYSLOG_X509_NAME_oneline(X509CERT) X509_get_subject_name(X509CERT)
+ #define RSYSLOG_BIO_method_name(SSLBIO) BIO_method_name(SSLBIO)
+ #define RSYSLOG_BIO_number_read(SSLBIO) BIO_number_read(SSLBIO)
+ #define RSYSLOG_BIO_number_written(SSLBIO) BIO_number_written(SSLBIO)
+ #else
+ #define RSYSLOG_X509_NAME_oneline(X509CERT) (X509CERT != NULL ? X509CERT->cert_info->subject : NULL)
+ #define RSYSLOG_BIO_method_name(SSLBIO) SSLBIO->method->name
+ #define RSYSLOG_BIO_number_read(SSLBIO) SSLBIO->num
+ #define RSYSLOG_BIO_number_written(SSLBIO) SSLBIO->num
+ #endif
+
+#endif
+
+char *test_rs_strerror_r(int errnum, char *buf, size_t buflen) {
+#ifndef HAVE_STRERROR_R
+ char *pszErr;
+ pszErr = strerror(errnum);
+ snprintf(buf, buflen, "%s", pszErr);
+#else
+# ifdef STRERROR_R_CHAR_P
+ char *p = strerror_r(errnum, buf, buflen);
+ if (p != buf) {
+ strncpy(buf, p, buflen);
+ buf[buflen - 1] = '\0';
+ }
+# else
+ strerror_r(errnum, buf, buflen);
+# endif
+#endif /* #ifdef __hpux */
+ return buf;
+}
+
+#define INVALID_SOCKET -1
+/* Name of input file, must match $IncludeConfig in test suite .conf files */
+#define NETTEST_INPUT_CONF_FILE "nettest.input.conf"
+/* name of input file, must match $IncludeConfig in .conf files */
+
+#define MAX_EXTRADATA_LEN 512*1024
+#define MAX_SENDBUF 2 * MAX_EXTRADATA_LEN
+#define MAX_RCVBUF 16 * 1024 + 1/* TLS RFC 8449: max size of buffer for message reception */
+
+static char *targetIP = "127.0.0.1";
+static char *msgPRI = "167";
+static int targetPort[5] = {13514};
+static int numTargetPorts = 1;
+static int verbose = 0;
+static int dynFileIDs = 0;
+static int extraDataLen = 0; /* amount of extra data to add to message */
+static int useRFC5424Format = 0; /* should the test message be in RFC5424 format? */
+static int bRandomizeExtraData = 0; /* randomize amount of extra data added */
+static int numMsgsToSend = 1; /* number of messages to send */
+static int numConnections = 1; /* number of connections to create */
+static int softLimitConnections = 0; /* soft connection limit, see -c option description */
+static int *sockArray; /* array of sockets to use */
+#ifdef ENABLE_RELP
+static relpClt_t **relpCltArray; /* array of sockets to use */
+#endif
+static int msgNum = 0; /* initial message number to start with */
+static int bShowProgress = 1; /* show progress messages */
+static int bSilent = 0; /* completely silent operation */
+static int bRandConnDrop = 0; /* randomly drop connections? */
+static double dbRandConnDrop = 0.95; /* random drop probability */
+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) */
+static int numRuns = 1; /* number of times the test shall be run */
+static int sleepBetweenRuns = 30; /* number of seconds to sleep between runs */
+static int bStatsRecords = 0; /* generate stats records */
+static int bCSVoutput = 0; /* generate output in CSV (where applicable) */
+static long long batchsize = 100000000ll;
+static int waittime = 0;
+static int runMultithreaded = 0; /* run tests in multithreaded mode */
+static int numThrds = 1; /* number of threads to use */
+static int abortOnSendFail = 1; /* abort run if sending fails? */
+static char *tlsCAFile = NULL;
+static char *tlsCertFile = NULL;
+static char *tlsKeyFile = NULL;
+static char *relpAuthMode = NULL;
+static char *relpPermittedPeer = NULL;
+#if defined(HAVE_RELPENGINESETTLSLIBBYNAME)
+static char *relpTlsLib = NULL;
+#endif
+
+static int tlsLogLevel = 0;
+static char *jsonCookie = NULL; /* if non-NULL, use JSON format with this cookie */
+static int octateCountFramed = 0;
+static char *customConfig = NULL; /* Stores a string with custom configuration passed through the TLS driver */
+
+#ifdef ENABLE_GNUTLS
+static gnutls_session_t *sessArray; /* array of TLS sessions to use */
+static gnutls_certificate_credentials_t tlscred;
+#endif
+
+#ifdef ENABLE_OPENSSL
+/* Main OpenSSL CTX pointer */
+static SSL_CTX *ctx;
+static SSL **sslArray;
+static struct sockaddr_in dtls_client_addr; /* socket address sender for receiving DTLS data */
+static int udpsockin; /* socket for receiving messages in DTLS mode */
+#endif
+
+/* variables for managing multi-threaded operations */
+int runningThreads; /* number of threads currently running */
+int doRun; /* shall sender thread begin to run? */
+pthread_mutex_t thrdMgmt; /* mutex for controling startup/shutdown */
+pthread_cond_t condStarted;
+pthread_cond_t condDoRun;
+
+/* the following struct provides information for a generator instance (thread) */
+struct instdata {
+ /* lower and upper bounds for the thread in question */
+ unsigned long long lower;
+ unsigned long long numMsgs; /* number of messages to send */
+ unsigned long long numSent; /* number of messages already sent */
+ unsigned idx; /**< index of fd to be used for sending */
+ pthread_t thread; /**< thread processing this instance */
+} *instarray = NULL;
+
+/* the following structure is used to gather performance data */
+struct runstats {
+ unsigned long long totalRuntime;
+ unsigned long minRuntime;
+ unsigned long maxRuntime;
+ int numRuns;
+};
+
+static int udpsockout; /* socket for sending in UDP mode */
+static struct sockaddr_in udpRcvr; /* remote receiver in UDP mode */
+
+static enum { TP_UDP, TP_TCP, TP_TLS, TP_RELP_PLAIN, TP_RELP_TLS, TP_DTLS } transport = TP_TCP;
+
+/* forward definitions */
+static void initTLSSess(int);
+static int sendTLS(int i, char *buf, size_t lenBuf);
+static void closeTLSSess(int __attribute__((unused)) i);
+
+static void initDTLSSess(void);
+static int sendDTLS(char *buf, size_t lenBuf);
+static void closeDTLSSess(void);
+
+#ifdef ENABLE_RELP
+/* RELP subsystem */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-security"
+static void relp_dbgprintf(char __attribute__((unused)) *fmt, ...) {
+ printf(fmt);
+}
+#pragma GCC diagnostic pop
+
+static relpEngine_t *pRelpEngine;
+#define CHKRELP(f) if(f != RELP_RET_OK) { fprintf(stderr, "%s\n", #f); exit(1); }
+
+static void
+onErr(void *pUsr, char *objinfo, char* errmesg, __attribute__((unused)) relpRetVal errcode)
+{
+ fprintf(stderr, "tcpflood: onErr '%s'\n", errmesg);
+}
+
+static void
+onGenericErr(char *objinfo, char* errmesg, __attribute__((unused)) relpRetVal errcode)
+{
+ fprintf(stderr, "tcpflood: onGenericErr '%s'\n", errmesg);
+}
+
+static void
+onAuthErr(void *pUsr, char *authinfo, char* errmesg, __attribute__((unused)) relpRetVal errcode)
+{
+ fprintf(stderr, "tcpflood: onAuthErr '%s' peer '%s'\n", errmesg, authinfo);
+}
+
+static void
+initRELP_PLAIN(void)
+{
+ CHKRELP(relpEngineConstruct(&pRelpEngine));
+ CHKRELP(relpEngineSetDbgprint(pRelpEngine,
+ verbose ? relp_dbgprintf : NULL));
+ CHKRELP(relpEngineSetEnableCmd(pRelpEngine, (unsigned char*)"syslog",
+ eRelpCmdState_Required));
+ /* Error output support */
+ CHKRELP(relpEngineSetOnErr(pRelpEngine, onErr));
+ CHKRELP(relpEngineSetOnGenericErr(pRelpEngine, onGenericErr));
+ CHKRELP(relpEngineSetOnAuthErr(pRelpEngine, onAuthErr));
+
+}
+#endif /* #ifdef ENABLE_RELP */
+
+/* prepare send subsystem for UDP send */
+static int
+setupUDP(void)
+{
+ if((udpsockout = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+ return 1;
+
+ memset((char *) &udpRcvr, 0, sizeof(udpRcvr));
+ udpRcvr.sin_family = AF_INET;
+ udpRcvr.sin_port = htons(targetPort[0]);
+ if(inet_aton(targetIP, &udpRcvr.sin_addr)==0) {
+ fprintf(stderr, "inet_aton() failed\n");
+ return(1);
+ }
+
+ return 0;
+}
+
+#if defined(ENABLE_OPENSSL)
+static int
+setupDTLS(void)
+{
+ // Setup receiving Socket for DTLS
+ if((udpsockin = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ return 1;
+
+ memset(&dtls_client_addr, 0, sizeof(dtls_client_addr));
+ dtls_client_addr.sin_family = AF_INET;
+ dtls_client_addr.sin_port = htons(0);
+ dtls_client_addr.sin_addr.s_addr = INADDR_ANY;
+ if (bind(udpsockin, (struct sockaddr*)&dtls_client_addr, sizeof(dtls_client_addr)) < 0) {
+ perror("bind()");
+ fprintf(stderr, "Unable to bind DTLS CLient socket\n");
+ return(1);
+ }
+
+ memset((char *) &udpRcvr, 0, sizeof(udpRcvr));
+ udpRcvr.sin_family = AF_INET;
+ udpRcvr.sin_port = htons(targetPort[0]);
+ if(inet_aton(targetIP, &udpRcvr.sin_addr)==0) {
+ fprintf(stderr, "inet_aton() failed\n");
+ return(1);
+ }
+
+ // Init Socket Connection (Which technically does not connect but prepares socket for DTLS)
+ printf("[DEBUG] Init Session to %s:%d ...\n", targetIP, targetPort[0]);
+ udpsockout = socket(AF_INET, SOCK_DGRAM, 0);
+ // Connect the UDP socket to the server's address
+ if (connect(udpsockout, (const struct sockaddr *) &udpRcvr, sizeof(udpRcvr)) < 0) {
+ perror("connect()");
+ fprintf(stderr, "connect to %s:%d failed\n", targetIP, targetPort[0]);
+ return(1);
+ }
+ sockArray[0] = -1;
+
+ return 0;
+}
+#endif
+
+/* open a single tcp connection
+ */
+int openConn(int *fd, const int connIdx)
+{
+ int sock;
+ struct sockaddr_in addr;
+ int port;
+ int retries = 0;
+ int rnd;
+
+ /* randomize port if required */
+ if(numTargetPorts > 1) {
+ rnd = rand(); /* easier if we need value for debug messages ;) */
+ port = targetPort[(rnd % numTargetPorts)];
+ } else {
+ port = targetPort[0];
+ }
+ if(transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) {
+ #ifdef ENABLE_RELP
+ relpRetVal relp_r;
+ relpClt_t *relpClt;
+ char relpPort[16];
+ snprintf(relpPort, sizeof(relpPort), "%d", port);
+ CHKRELP(relpEngineCltConstruct(pRelpEngine, &relpClt));
+ if(transport == TP_RELP_TLS) {
+ #if defined(HAVE_RELPENGINESETTLSLIBBYNAME)
+ if(relpTlsLib != NULL && relpEngineSetTLSLibByName(pRelpEngine, relpTlsLib) != RELP_RET_OK) {
+ fprintf(stderr, "relpTlsLib not accepted by librelp, using default\n");
+ }
+ #endif
+ if(relpCltEnableTLS(relpClt) != RELP_RET_OK) {
+ fprintf(stderr, "error while enabling TLS for relp\n");
+ exit(1);
+ }
+ if(relpAuthMode != NULL && relpCltSetAuthMode(relpClt, relpAuthMode) != RELP_RET_OK) {
+ fprintf(stderr, "could not set Relp Authentication mode: %s\n", relpAuthMode);
+ exit(1);
+ }
+ if(tlsCAFile != NULL && relpCltSetCACert(relpClt, tlsCAFile) != RELP_RET_OK) {
+ fprintf(stderr, "could not set CA File: %s\n", tlsCAFile);
+ exit(1);
+ }
+ if(tlsCertFile != NULL && relpCltSetOwnCert(relpClt, tlsCertFile) != RELP_RET_OK) {
+ fprintf(stderr, "could not set Cert File: %s\n", tlsCertFile);
+ exit(1);
+ }
+ if(tlsKeyFile != NULL && relpCltSetPrivKey(relpClt, tlsKeyFile) != RELP_RET_OK) {
+ fprintf(stderr, "could not set Key File: %s\n", tlsKeyFile);
+ exit(1);
+ }
+ if(relpPermittedPeer != NULL && relpCltAddPermittedPeer(relpClt, relpPermittedPeer)
+ != RELP_RET_OK) {
+ fprintf(stderr, "could not set Permitted Peer: %s\n", relpPermittedPeer);
+ exit(1);
+ }
+#if defined(HAVE_RELPENGINESETTLSCFGCMD)
+ /* Check for Custom Config string */
+ if(customConfig != NULL && relpCltSetTlsConfigCmd(relpClt, customConfig)
+ != RELP_RET_OK) {
+ fprintf(stderr, "could not set custom tls command: %s\n", customConfig);
+ exit(1);
+ }
+#endif
+ }
+ relpCltArray[connIdx] = relpClt;
+ relp_r = relpCltConnect(relpCltArray[connIdx], 2,
+ (unsigned char*)relpPort, (unsigned char*)targetIP);
+ if(relp_r != RELP_RET_OK) {
+ fprintf(stderr, "relp connect failed with return %d\n", relp_r);
+ return(1);
+ }
+ *fd = 1; /* mimic "all ok" state */
+ #endif
+ } else { /* TCP, with or without TLS */
+ if((sock=socket(AF_INET, SOCK_STREAM, 0))==-1) {
+ perror("\nsocket()");
+ return(1);
+ }
+ 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");
+ return(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(%d) failed\n", port);
+ return(1);
+ } else {
+ usleep(100000); /* ms = 1000 us! */
+ }
+ }
+ }
+
+ *fd = sock;
+ }
+ return 0;
+}
+
+
+/* open all requested tcp connections
+ * this includes allocating the connection array
+ */
+int openConnections(void)
+{
+ int i;
+ char msgBuf[128];
+ size_t lenMsg;
+
+ if(transport == TP_UDP)
+ return setupUDP();
+
+ if(bShowProgress)
+ if(write(1, " open connections", sizeof(" open connections")-1)){}
+# if defined(ENABLE_OPENSSL)
+ sslArray = calloc(numConnections, sizeof(SSL *));
+# elif defined(ENABLE_GNUTLS)
+ sessArray = calloc(numConnections, sizeof(gnutls_session_t));
+# endif
+ sockArray = calloc(numConnections, sizeof(int));
+
+# if defined(ENABLE_OPENSSL)
+ // Use setupDTLS on DTLS
+ if(transport == TP_DTLS)
+ return setupDTLS();
+# endif
+
+ #ifdef ENABLE_RELP
+ if(transport == TP_RELP_PLAIN || transport == TP_RELP_TLS)
+ relpCltArray = calloc(numConnections, sizeof(relpClt_t*));
+ #endif
+ for(i = 0 ; i < numConnections ; ++i) {
+ if(i % 10 == 0) {
+ if(bShowProgress)
+ printf("\r%5.5d", i);
+ }
+ if(openConn(&(sockArray[i]), i) != 0) {
+ printf("error in trying to open connection i=%d\n", i);
+ if(softLimitConnections) {
+ printf("Connection limit is soft, continuing with fewer connections\n");
+ numConnections = i - 1;
+ int close_conn = 10;
+ for(i -= 1 ; close_conn > 0 && i > 1 ; --i, --close_conn) {
+ printf("closing connection %d to make some room\n", i);
+ /* close at least some connections so that
+ * other functionality has a chance to do
+ * at least something.
+ */
+ if(transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) {
+ #ifdef ENABLE_RELP
+ CHKRELP(relpEngineCltDestruct(pRelpEngine,
+ relpCltArray+i));
+ #endif
+ } else { /* TCP and TLS modes */
+ if(transport == TP_TLS)
+ closeTLSSess(i);
+ close(sockArray[i]);
+ }
+ sockArray[i] = -1;
+ }
+ numConnections = i;
+ printf("continuing with %d connections.\n", numConnections);
+ if(numConnections < 1) {
+ fprintf(stderr, "tcpflood could not open at least one "
+ "connection, error-terminating\n");
+ exit(1);
+ }
+ break;
+ }
+ return 1;
+ }
+ if(transport == TP_TLS) {
+ initTLSSess(i);
+ }
+ }
+ if(bShowProgress) {
+ lenMsg = sprintf(msgBuf, "\r%5.5d open connections\n", i);
+ if(write(1, msgBuf, lenMsg)) {}
+ }
+
+ return 0;
+}
+
+
+/* we also close all connections because otherwise we may get very bad
+ * timing for the syslogd - it may not be able to process all incoming
+ * messages fast enough if we immediately shut down.
+ * TODO: it may be an interesting excercise to handle that situation
+ * at the syslogd level, too
+ * rgerhards, 2009-04-14
+ */
+void closeConnections(void)
+{
+ int i;
+ size_t lenMsg;
+ struct linger ling;
+ char msgBuf[128];
+
+ if(transport == TP_UDP) {
+ return;
+ }
+# if defined(ENABLE_OPENSSL)
+ else if(transport == TP_DTLS) {
+ closeDTLSSess();
+ return;
+ }
+# endif
+
+ if(bShowProgress)
+ if(write(1, " close connections", sizeof(" close connections")-1)){}
+ for(i = 0 ; i < numConnections ; ++i) {
+ if(i % 10 == 0 && bShowProgress) {
+ lenMsg = sprintf(msgBuf, "\r%5.5d", i);
+ if(write(1, msgBuf, lenMsg)){}
+ }
+ if(transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) {
+ #ifdef ENABLE_RELP
+ relpRetVal relpr;
+ if(sockArray[i] != -1) {
+ relpr = relpEngineCltDestruct(pRelpEngine, relpCltArray+i);
+ if(relpr != RELP_RET_OK) {
+ fprintf(stderr, "relp error %d on close\n", relpr);
+ }
+ sockArray[i] = -1;
+ }
+ #endif
+ } else { /* TCP and TLS modes */
+ 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));
+ if(transport == TP_TLS) {
+ closeTLSSess(i);
+ }
+ close(sockArray[i]);
+ }
+ }
+ }
+ if(bShowProgress) {
+ lenMsg = sprintf(msgBuf, "\r%5.5d close connections\n", i);
+ if(write(1, msgBuf, lenMsg)){}
+ }
+
+}
+
+
+/* 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 void
+genMsg(char *buf, size_t maxBuf, size_t *pLenBuf, struct instdata *inst)
+{
+ int edLen; /* actual extra data length to use */
+ char extraData[MAX_EXTRADATA_LEN + 1];
+ char dynFileIDBuf[128] = "";
+ int done;
+ char payloadLen[32];
+ int payloadStringLen;
+
+ if(dataFP != NULL) {
+ /* get message from file */
+ do {
+ done = 1;
+ *pLenBuf = fread(buf, 1, MAX_EXTRADATA_LEN + 1024, dataFP);
+ if(*pLenBuf == 0) {
+ if(--numFileIterations > 0) {
+ rewind(dataFP);
+ done = 0; /* need new iteration */
+ } else {
+ *pLenBuf = 0;
+ goto finalize_it;
+ }
+ }
+ } while(!done); /* Attention: do..while()! */
+ } else if(jsonCookie != NULL) {
+ if(useRFC5424Format) {
+ *pLenBuf = snprintf(buf, maxBuf, "<%s>1 2003-03-01T01:00:00.000Z mymachine.example.com "
+ "tcpflood - tag [tcpflood@32473 MSGNUM"
+ "=\"%8.8d\"] %s{\"msgnum\":%d}%c", msgPRI, msgNum,
+ jsonCookie, msgNum, frameDelim);
+ } else {
+ *pLenBuf = snprintf(buf, maxBuf, "<%s>Mar 1 01:00:00 172.20.245.8 tag %s{\"msgnum\":%d}%c",
+ msgPRI, jsonCookie, msgNum, frameDelim);
+ }
+ } else if(MsgToSend == NULL) {
+ if(dynFileIDs > 0) {
+ snprintf(dynFileIDBuf, sizeof(dynFileIDBuf), "%d:", rand() % dynFileIDs);
+ }
+ if(extraDataLen == 0) {
+ if(useRFC5424Format) {
+ *pLenBuf = snprintf(buf, maxBuf, "<%s>1 2003-03-01T01:00:00.000Z "
+ "mymachine.example.com tcpflood - tag [tcpflood@32473 "
+ "MSGNUM=\"%8.8d\"] msgnum:%s%8.8d:%c",
+ msgPRI, msgNum, dynFileIDBuf, msgNum, frameDelim);
+ } else {
+ *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 = ((unsigned long) rand() + extraDataLen) % extraDataLen + 1;
+ else
+ edLen = extraDataLen;
+ memset(extraData, 'X', edLen);
+ extraData[edLen] = '\0';
+ if(useRFC5424Format) {
+ *pLenBuf = snprintf(buf, maxBuf, "<%s>1 2003-03-01T01:00:00.000Z "
+ "mymachine.example.com tcpflood - tag [tcpflood@32473 "
+ "MSGNUM=\"%8.8d\"] msgnum:%s%8.8d:%c",
+ msgPRI, msgNum, dynFileIDBuf, msgNum, frameDelim);
+ } else {
+ *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%c", MsgToSend, frameDelim);
+ }
+ if (octateCountFramed == 1) {
+ snprintf(payloadLen, sizeof(payloadLen), "%zd ", *pLenBuf);
+ payloadStringLen = strlen(payloadLen);
+ memmove(buf + payloadStringLen, buf, *pLenBuf);
+ memcpy(buf, payloadLen, payloadStringLen);
+ *pLenBuf += payloadStringLen;
+ }
+ ++inst->numSent;
+
+finalize_it: /*EMPTY to keep the compiler happy */;
+}
+
+
+static int
+sendPlainTCP(const int socknum, const char *const buf, const size_t lenBuf, int *const ret_errno)
+{
+ size_t lenSent;
+ int r;
+
+ lenSent = 0;
+ while(lenSent != lenBuf) {
+ r = send(sockArray[socknum], buf + lenSent, lenBuf - lenSent, 0);
+ if(r > 0) {
+ lenSent += r;
+ } else {
+ *ret_errno = errno;
+ goto finalize_it;
+ }
+ }
+
+finalize_it:
+ return lenSent;
+}
+
+
+/* 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
+ * for extracton to field-based properties.
+ * The first numConnection messages are sent sequentially, as are the
+ * last. All messages in between are sent over random connections.
+ * Note that message numbers start at 0.
+ */
+int sendMessages(struct instdata *inst)
+{
+ unsigned i = 0;
+ int socknum;
+ size_t lenBuf;
+ size_t lenSend = 0;
+ char *statusText = "";
+ char buf[MAX_EXTRADATA_LEN + 1024];
+ char sendBuf[MAX_SENDBUF];
+ int offsSendBuf = 0;
+ char errStr[1024];
+ int error_number = 0;
+ unsigned show_progress_interval = 100;
+
+ if(!bSilent) {
+ if(dataFile == NULL) {
+ printf("Sending %llu messages.\n", inst->numMsgs);
+ statusText = "messages";
+ if ((inst->numMsgs / 100) > show_progress_interval) {
+ show_progress_interval = inst->numMsgs / 100;
+ }
+ } else {
+ printf("Sending file '%s' %d times.\n", dataFile,
+ numFileIterations);
+ statusText = "kb";
+ }
+ }
+ if(bShowProgress)
+ printf("\r%8.8d %s sent", 0, statusText);
+ while(i < inst->numMsgs) {
+ if(runMultithreaded) {
+ socknum = inst->idx;
+ } else {
+ if((int) i < numConnections)
+ socknum = i;
+ else if(i >= inst->numMsgs - numConnections) {
+ socknum = i - (inst->numMsgs - numConnections);
+ } else {
+ int rnd = rand();
+ socknum = rnd % numConnections;
+ }
+ }
+ genMsg(buf, sizeof(buf), &lenBuf, inst); /* generate the message to send according to params */
+ if(lenBuf == 0)
+ break; /* terminate when no message could be generated */
+ if(transport == TP_TCP) {
+ if(sockArray[socknum] == -1) {
+ /* connection was dropped, need to re-establish */
+ if(openConn(&(sockArray[socknum]), socknum) != 0) {
+ printf("error in trying to re-open connection %d\n", socknum);
+ exit(1);
+ }
+ }
+ lenSend = sendPlainTCP(socknum, buf, lenBuf, &error_number);
+ } else if(transport == TP_UDP) {
+ lenSend = sendto(udpsockout, buf, lenBuf, 0, &udpRcvr, sizeof(udpRcvr));
+ error_number = errno;
+ } else if(transport == TP_TLS) {
+ if(sockArray[socknum] == -1) {
+ /* connection was dropped, need to re-establish */
+ if(openConn(&(sockArray[socknum]), socknum) != 0) {
+ printf("error in trying to re-open connection %d\n", socknum);
+ exit(1);
+ }
+ initTLSSess(socknum);
+ }
+ if(offsSendBuf + lenBuf < MAX_SENDBUF) {
+ memcpy(sendBuf+offsSendBuf, buf, lenBuf);
+ offsSendBuf += lenBuf;
+ lenSend = lenBuf; /* simulate "good" call */
+ } else {
+ lenSend = sendTLS(socknum, sendBuf, offsSendBuf);
+ lenSend = (lenSend == offsSendBuf) ? lenBuf : -1;
+ memcpy(sendBuf, buf, lenBuf);
+ offsSendBuf = lenBuf;
+ }
+# if defined(ENABLE_OPENSSL)
+ } else if(transport == TP_DTLS) {
+ if(sockArray[0] == -1) {
+ // Init DTLS Session (Bind local listener)
+ initDTLSSess();
+ }
+ lenSend = sendDTLS(buf, lenBuf);
+# endif
+ } else if(transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) {
+ #ifdef ENABLE_RELP
+ relpRetVal relp_ret;
+ if(sockArray[socknum] == -1) {
+ /* connection was dropped, need to re-establish */
+ if(openConn(&(sockArray[socknum]), socknum) != 0) {
+ printf("error in trying to re-open connection %d\n", socknum);
+ exit(1);
+ }
+ }
+ relp_ret = relpCltSendSyslog(relpCltArray[socknum],
+ (unsigned char*)buf, lenBuf);
+ if (relp_ret == RELP_RET_OK) {
+ lenSend = lenBuf; /* mimic ok */
+ } else {
+ lenSend = 0; /* mimic fail */
+ printf("\nrelpCltSendSyslog() failed with relp error code %d\n",
+ relp_ret);
+ }
+ #endif
+ }
+ if(lenSend != lenBuf) {
+ printf("\r%5.5u\n", i);
+ fflush(stdout);
+ test_rs_strerror_r(error_number, errStr, sizeof(errStr));
+ if(lenSend == 0) {
+ printf("tcpflood: socket %d, index %u, msgNum %lld CLOSED REMOTELY\n",
+ sockArray[socknum], i, inst->numSent);
+ } else {
+ printf("tcpflood: send() failed \"%s\" at socket %d, index %u, "
+ "msgNum %lld, lenSend %zd, lenBuf %zd\n",
+ errStr, sockArray[socknum], i, inst->numSent, lenSend,
+ lenBuf);
+ }
+ fflush(stderr);
+
+ if(abortOnSendFail) {
+ printf("tcpflood terminates due to send failure\n");
+ return(1);
+ }
+ }
+ if(i % show_progress_interval == 0) {
+ if(bShowProgress)
+ printf("\r%8.8u", i);
+ }
+ if(!runMultithreaded && bRandConnDrop) {
+ /* if we need to randomly drop connections, see if we
+ * are a victim
+ */
+ if(rand() > (int) (RAND_MAX * dbRandConnDrop)) {
+#if 1
+ if(transport == TP_TLS && offsSendBuf != 0) {
+ /* send remaining buffer */
+ lenSend = sendTLS(socknum, sendBuf, offsSendBuf);
+ if(lenSend != offsSendBuf) {
+ fprintf(stderr, "tcpflood: error in send function causes potential "
+ "data loss lenSend %zd, offsSendBuf %d\n",
+ lenSend, offsSendBuf);
+ }
+ offsSendBuf = 0;
+ }
+#endif
+ ++nConnDrops;
+ close(sockArray[socknum]);
+ sockArray[socknum] = -1;
+ }
+ }
+ if(inst->numSent % batchsize == 0) {
+ usleep(waittime);
+ }
+ ++msgNum;
+ ++i;
+ }
+ if(transport == TP_TLS && offsSendBuf != 0) {
+ /* send remaining buffer */
+ lenSend = sendTLS(socknum, sendBuf, offsSendBuf);
+ }
+ if(!bSilent)
+ printf("\r%8.8u %s sent\n", i, statusText);
+
+ return 0;
+}
+
+
+/* this is the thread that starts a generator
+ */
+static void *
+thrdStarter(void *arg)
+{
+ struct instdata *inst = (struct instdata*) arg;
+ pthread_mutex_lock(&thrdMgmt);
+ runningThreads++;
+ pthread_cond_signal(&condStarted);
+ while(doRun == 0) {
+ pthread_cond_wait(&condDoRun, &thrdMgmt);
+ }
+ pthread_mutex_unlock(&thrdMgmt);
+ if(sendMessages(inst) != 0) {
+ printf("error sending messages\n");
+ }
+ return NULL;
+}
+
+
+/* This function initializes the actual traffic generators. The function sets up all required
+ * parameter blocks and starts threads. It returns when all threads are ready to run
+ * and the main task must just enable them.
+ */
+static void
+prepareGenerators()
+{
+ int i;
+ long long msgsThrd;
+ long long starting = 0;
+ pthread_attr_t thrd_attr;
+
+ if(runMultithreaded) {
+ bSilent = 1;
+ numThrds = numConnections;
+ } else {
+ numThrds = 1;
+ }
+
+ pthread_attr_init(&thrd_attr);
+ pthread_attr_setstacksize(&thrd_attr, 4096*1024);
+
+ runningThreads = 0;
+ doRun = 0;
+ pthread_mutex_init(&thrdMgmt, NULL);
+ pthread_cond_init(&condStarted, NULL);
+ pthread_cond_init(&condDoRun, NULL);
+
+ if(instarray != NULL) {
+ free(instarray);
+ }
+ instarray = calloc(numThrds, sizeof(struct instdata));
+ msgsThrd = numMsgsToSend / numThrds;
+
+ for(i = 0 ; i < numThrds ; ++i) {
+ instarray[i].lower = starting;
+ instarray[i].numMsgs = msgsThrd;
+ instarray[i].numSent = 0;
+ instarray[i].idx = i;
+ pthread_create(&(instarray[i].thread), &thrd_attr, thrdStarter, instarray + i);
+ /*printf("started thread %x\n", (unsigned) instarray[i].thread);*/
+ starting += msgsThrd;
+ }
+}
+
+/* Let all generators run. Threads must have been started. Here we wait until
+ * all threads are initialized and then broadcast that they can begin to run.
+ */
+static void
+runGenerators()
+{
+ pthread_mutex_lock(&thrdMgmt);
+ while(runningThreads != numThrds){
+ pthread_cond_wait(&condStarted, &thrdMgmt);
+ }
+ doRun = 1;
+ pthread_cond_broadcast(&condDoRun);
+ pthread_mutex_unlock(&thrdMgmt);
+}
+
+
+/* Wait for all traffic generators to stop.
+ */
+static void
+waitGenerators()
+{
+ int i;
+ for(i = 0 ; i < numThrds ; ++i) {
+ pthread_join(instarray[i].thread, NULL);
+ /*printf("thread %x stopped\n", (unsigned) instarray[i].thread);*/
+ }
+ pthread_mutex_destroy(&thrdMgmt);
+ pthread_cond_destroy(&condStarted);
+ pthread_cond_destroy(&condDoRun);
+}
+
+/* functions related to computing statistics on the runtime of a test. This is
+ * a separate function primarily not to mess up the test driver.
+ * rgerhards, 2010-12-08
+ */
+static void
+endTiming(struct timeval *tvStart, struct runstats *stats)
+{
+ long sec, usec;
+ unsigned long runtime;
+ struct timeval tvEnd;
+
+ gettimeofday(&tvEnd, NULL);
+ if(tvStart->tv_usec > tvEnd.tv_usec) {
+ tvEnd.tv_sec--;
+ tvEnd.tv_usec += 1000000;
+ }
+
+ sec = tvEnd.tv_sec - tvStart->tv_sec;
+ usec = tvEnd.tv_usec - tvStart->tv_usec;
+
+ runtime = sec * 1000 + (usec / 1000);
+ stats->totalRuntime += runtime;
+ if(runtime < stats->minRuntime)
+ stats->minRuntime = runtime;
+ if(runtime > stats->maxRuntime)
+ stats->maxRuntime = runtime;
+
+ if(!bSilent || bStatsRecords) {
+ if(bCSVoutput) {
+ printf("%lu.%3.3ld\n", runtime / 1000, runtime % 1000);
+ } else {
+ printf("runtime: %lu.%3.3ld\n", runtime / 1000, runtime % 1000);
+ }
+ }
+}
+
+
+/* generate stats summary record at end of run
+ */
+static void
+genStats(struct runstats *stats)
+{
+ long unsigned avg;
+ avg = stats->totalRuntime / stats->numRuns;
+
+ if(bCSVoutput) {
+ printf("#numRuns,TotalRuntime,AvgRuntime,MinRuntime,MaxRuntime\n");
+ printf("%d,%llu.%3.3d,%lu.%3.3lu,%lu.%3.3lu,%lu.%3.3lu\n",
+ stats->numRuns,
+ stats->totalRuntime / 1000, (int) stats->totalRuntime % 1000,
+ avg / 1000, avg % 1000,
+ stats->minRuntime / 1000, stats->minRuntime % 1000,
+ stats->maxRuntime / 1000, stats->maxRuntime % 1000);
+ } else {
+ printf("Runs: %d\n", stats->numRuns);
+ printf("Runtime:\n");
+ printf(" total: %llu.%3.3d\n", stats->totalRuntime / 1000,
+ (int) stats->totalRuntime % 1000);
+ printf(" avg: %lu.%3.3lu\n", avg / 1000, avg % 1000);
+ printf(" min: %lu.%3.3lu\n", stats->minRuntime / 1000, stats->minRuntime % 1000);
+ printf(" max: %lu.%3.3lu\n", stats->maxRuntime / 1000, stats->maxRuntime % 1000);
+ printf("All times are wallclock time.\n");
+ }
+}
+
+
+/* Run the actual test. This function handles various meta-parameters, like
+ * a specified number of iterations, performance measurement and so on...
+ * rgerhards, 2010-12-08
+ */
+static int
+runTests(void)
+{
+ struct timeval tvStart;
+ struct runstats stats;
+ int run;
+
+ stats.totalRuntime = 0;
+ stats.minRuntime = 0xffffffffllu;
+ stats.maxRuntime = 0;
+ stats.numRuns = numRuns;
+ run = 1;
+ while(1) { /* loop broken inside */
+ if(!bSilent)
+ printf("starting run %d\n", run);
+ prepareGenerators();
+ gettimeofday(&tvStart, NULL);
+ runGenerators();
+ waitGenerators();
+ endTiming(&tvStart, &stats);
+ if(run == numRuns)
+ break;
+ if(!bSilent)
+ printf("sleeping %d seconds before next run\n", sleepBetweenRuns);
+ sleep(sleepBetweenRuns);
+ ++run;
+ }
+
+ if(bStatsRecords) {
+ genStats(&stats);
+ }
+
+ return 0;
+}
+
+# if defined(ENABLE_OPENSSL)
+/* OpenSSL implementation of TLS funtions.
+ * alorbach, 2018-06-11
+ */
+
+long BIO_debug_callback(BIO *bio, int cmd, const char __attribute__((unused)) *argp,
+ int argi, long __attribute__((unused)) argl, long ret)
+{
+ long r = 1;
+
+ if (BIO_CB_RETURN & cmd)
+ r = ret;
+
+ printf("tcpflood: openssl debugmsg: BIO[%p]: ", (void *)bio);
+
+ switch (cmd) {
+ case BIO_CB_FREE:
+ printf("Free - %s\n", RSYSLOG_BIO_method_name(bio));
+ break;
+/* Disabled due API changes for OpenSSL 1.1.0+ */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ case BIO_CB_READ:
+ if (bio->method->type & BIO_TYPE_DESCRIPTOR)
+ printf("read(%d,%lu) - %s fd=%d\n",
+ RSYSLOG_BIO_number_read(bio), (unsigned long)argi,
+ RSYSLOG_BIO_method_name(bio), RSYSLOG_BIO_number_read(bio));
+ else
+ printf("read(%d,%lu) - %s\n",
+ RSYSLOG_BIO_number_read(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio));
+ break;
+ case BIO_CB_WRITE:
+ if (bio->method->type & BIO_TYPE_DESCRIPTOR)
+ printf("write(%d,%lu) - %s fd=%d\n",
+ RSYSLOG_BIO_number_written(bio), (unsigned long)argi,
+ RSYSLOG_BIO_method_name(bio), RSYSLOG_BIO_number_written(bio));
+ else
+ printf("write(%d,%lu) - %s\n",
+ RSYSLOG_BIO_number_written(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio));
+ break;
+#else
+ case BIO_CB_READ:
+ printf("read %s\n", RSYSLOG_BIO_method_name(bio));
+ break;
+ case BIO_CB_WRITE:
+ printf("write %s\n", RSYSLOG_BIO_method_name(bio));
+ break;
+#endif
+ case BIO_CB_PUTS:
+ printf("puts() - %s\n", RSYSLOG_BIO_method_name(bio));
+ break;
+ case BIO_CB_GETS:
+ printf("gets(%lu) - %s\n", (unsigned long)argi,
+ RSYSLOG_BIO_method_name(bio));
+ break;
+ case BIO_CB_CTRL:
+ printf("ctrl(%lu) - %s\n", (unsigned long)argi,
+ RSYSLOG_BIO_method_name(bio));
+ break;
+ case BIO_CB_RETURN | BIO_CB_READ:
+ printf("read return %ld\n", ret);
+ break;
+ case BIO_CB_RETURN | BIO_CB_WRITE:
+ printf("write return %ld\n", ret);
+ break;
+ case BIO_CB_RETURN | BIO_CB_GETS:
+ printf("gets return %ld\n", ret);
+ break;
+ case BIO_CB_RETURN | BIO_CB_PUTS:
+ printf("puts return %ld\n", ret);
+ break;
+ case BIO_CB_RETURN | BIO_CB_CTRL:
+ printf("ctrl return %ld\n", ret);
+ break;
+ default:
+ printf("bio callback - unknown type (%d)\n", cmd);
+ break;
+ }
+
+ return (r);
+}
+
+void osslLastSSLErrorMsg(int ret, SSL *ssl, const char* pszCallSource)
+{
+ unsigned long un_error = 0;
+ char psz[256];
+
+ if (ssl == NULL) {
+ /* Output Error Info*/
+ printf("tcpflood: Error in '%s' with ret=%d\n", pszCallSource, ret);
+ } else {
+ long iMyRet = SSL_get_error(ssl, ret);
+
+ /* Check which kind of error we have */
+ printf("tcpflood: openssl error '%s' with error code=%ld\n", pszCallSource, iMyRet);
+ if(iMyRet == SSL_ERROR_SYSCALL){
+ iMyRet = ERR_get_error();
+ if(ret == 0) {
+ iMyRet = SSL_get_error(ssl, iMyRet);
+ if(iMyRet == 0) {
+ *psz = '\0';
+ } else {
+ ERR_error_string_n(iMyRet, psz, 256);
+ }
+ printf("tcpflood: Errno %d, SysErr: %s\n", errno, psz);
+ }
+ } else {
+ printf("tcpflood: Unknown SSL Error in '%s' (%d), SSL_get_error: %ld\n",
+ pszCallSource, ret, iMyRet);
+ }
+ }
+
+ /* Loop through errors */
+ while ((un_error = ERR_get_error()) > 0){
+ ERR_error_string_n(un_error, psz, 256);
+ printf("tcpflood: %s Errorstack: %s\n", pszCallSource, psz);
+ }
+}
+
+int verify_callback(int status, X509_STORE_CTX *store)
+{
+ char szdbgdata1[256];
+ char szdbgdata2[256];
+
+ if(status == 0) {
+ printf("tcpflood: verify_callback certificate validation failed!\n");
+
+ X509 *cert = X509_STORE_CTX_get_current_cert(store);
+ int depth = X509_STORE_CTX_get_error_depth(store);
+ int err = X509_STORE_CTX_get_error(store);
+ X509_NAME_oneline(X509_get_issuer_name(cert), szdbgdata1, sizeof(szdbgdata1));
+ X509_NAME_oneline(RSYSLOG_X509_NAME_oneline(cert), szdbgdata2, sizeof(szdbgdata2));
+
+ /* Log Warning only on EXPIRED */
+ if (err == X509_V_OK || err == X509_V_ERR_CERT_HAS_EXPIRED) {
+ printf(
+ "tcpflood: Certificate warning at depth: %d \n\t"
+ "issuer = %s\n\t"
+ "subject = %s\n\t"
+ "err %d:%s\n",
+ depth, szdbgdata1, szdbgdata2, err, X509_verify_cert_error_string(err));
+
+ /* Set Status to OK*/
+ status = 1;
+ } else {
+ printf(
+ "tcpflood: Certificate error at depth: %d \n\t"
+ "issuer = %s\n\t"
+ "subject = %s\n\t"
+ "err %d:%s\n",
+ depth, szdbgdata1, szdbgdata2, err, X509_verify_cert_error_string(err));
+ exit(1);
+ }
+ }
+ return status;
+}
+
+
+/* global init OpenSSL
+ */
+static void
+initTLS(const SSL_METHOD *method)
+{
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ /* Setup OpenSSL library < 1.1.0 */
+ if( !SSL_library_init()) {
+#else
+ /* Setup OpenSSL library >= 1.1.0 with system default settings */
+ if( OPENSSL_init_ssl(0, NULL) == 0) {
+#endif
+ printf("tcpflood: error openSSL initialization failed!\n");
+ exit(1);
+ }
+
+ /* Load readable error strings */
+ SSL_load_error_strings();
+ OpenSSL_add_ssl_algorithms();
+ ERR_load_BIO_strings();
+ ERR_load_crypto_strings();
+
+ // Create OpenSSL Context
+ ctx = SSL_CTX_new(method);
+
+ if(tlsCAFile != NULL && SSL_CTX_load_verify_locations(ctx, tlsCAFile, NULL) != 1) {
+ printf("tcpflood: Error, Failed loading CA certificate"
+ " Is the file at the right path? And do we have the permissions?");
+ exit(1);
+ }
+ SSL_CTX_set_ecdh_auto(ctx, 1);
+ if(SSL_CTX_use_certificate_chain_file(ctx, tlsCertFile) != 1) {
+ printf("tcpflood: error cert file could not be accessed -- have you mixed up key and certificate?\n");
+ printf("If in doubt, try swapping the files in -z/-Z\n");
+ printf("Certifcate is: '%s'\n", tlsCertFile);
+ printf("Key is: '%s'\n", tlsKeyFile);
+ exit(1);
+ }
+ if(SSL_CTX_use_PrivateKey_file(ctx, tlsKeyFile, SSL_FILETYPE_PEM) != 1) {
+ printf("tcpflood: error key file could not be accessed -- have you mixed up key and certificate?\n");
+ printf("If in doubt, try swapping the files in -z/-Z\n");
+ printf("Certifcate is: '%s'\n", tlsCertFile);
+ printf("Key is: '%s'\n", tlsKeyFile);
+ exit(1);
+ }
+
+ /* Set CTX Options */
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); /* Disable insecure SSLv2 Protocol */
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3); /* Disable insecure SSLv3 Protocol */
+ SSL_CTX_sess_set_cache_size(ctx,1024);
+
+ /* Check for Custom Config string */
+ if (customConfig != NULL){
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
+ char *pCurrentPos;
+ char *pNextPos;
+ char *pszCmd;
+ char *pszValue;
+ int iConfErr;
+
+ printf("tcpflood: custom config set to '%s'\n", customConfig);
+
+ /* Set working pointer */
+ pCurrentPos = (char*) customConfig;
+ if (strlen(pCurrentPos) > 0) {
+ pNextPos = index(pCurrentPos, '=');
+ if (pNextPos != NULL) {
+ pszCmd = strndup(pCurrentPos, pNextPos-pCurrentPos);
+ pszValue = strdup(++pNextPos);
+
+ // Create CTX Config Helper
+ SSL_CONF_CTX *cctx;
+ cctx = SSL_CONF_CTX_new();
+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
+ SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SHOW_ERRORS);
+ SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
+
+ /* Add SSL Conf Command */
+ iConfErr = SSL_CONF_cmd(cctx, pszCmd, pszValue);
+ if (iConfErr > 0) {
+ printf("tcpflood: Successfully added Command %s:%s\n",
+ pszCmd, pszValue);
+ }
+ else {
+ printf("tcpflood: error, adding Command: %s:%s "
+ "in SSL_CONF_cmd with error '%d'\n",
+ pszCmd, pszValue, iConfErr);
+ osslLastSSLErrorMsg(0, NULL, "initTLS");
+ }
+
+ /* Finalize SSL Conf */
+ iConfErr = SSL_CONF_CTX_finish(cctx);
+ if (!iConfErr) {
+ printf("tcpflood: error, setting openssl command parameters: %s\n",
+ customConfig);
+ }
+
+ free(pszCmd);
+ free(pszValue);
+ } else {
+ printf("tcpflood: error, invalid value for -k: %s\n", customConfig);
+ }
+ } else {
+ printf("tcpflood: error, invalid value for -k: %s\n", customConfig);
+ }
+#else
+ printf("tcpflood: TLS library does not support SSL_CONF_cmd API (maybe it is too old?).");
+#endif
+ }
+
+
+ /* DO ONLY SUPPORT DEFAULT CIPHERS YET
+ * SSL_CTX_set_cipher_list(ctx,"ALL"); Support all ciphers */
+
+/* // Create Extra Length DH!
+ pDH = DH_new();
+ if ( !DH_generate_parameters_ex(pDH, 768, DH_GENERATOR_2, NULL) )
+ {
+ if(pDH)
+ DH_free(pDH);
+
+ fprintf(stderr, "Failed to generated dynamic DH\n");
+ exit(1);
+ }
+ else
+ {
+ int iErrCheck = 0;
+ if ( !DH_check( pDH, &iErrCheck) )
+ {
+ fprintf(stderr, "Failed to generated dynamic DH - iErrCheck=%d\n", iErrCheck);
+ exit(1);
+ }
+ }
+*/
+ /* Set default VERIFY Options for OpenSSL CTX - and CALLBACK */
+ SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback);
+
+ SSL_CTX_set_timeout(ctx, 30); /* Default Session Timeout, TODO: Make configureable */
+ SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
+}
+
+static void
+exitTLS(void)
+{
+ SSL_CTX_free(ctx);
+ ENGINE_cleanup();
+ ERR_free_strings();
+ EVP_cleanup();
+ CRYPTO_cleanup_all_ex_data();
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
+static void
+initTLSSess(int i)
+{
+ int res;
+ BIO *bio_client;
+ SSL* pNewSsl = SSL_new(ctx);
+
+ sslArray[i] = pNewSsl;
+
+ if(!sslArray[i]) {
+ osslLastSSLErrorMsg(0, sslArray[i], "initTLSSess1");
+ }
+
+ SSL_set_verify(sslArray[i], SSL_VERIFY_NONE, verify_callback);
+
+ /* Create BIO from socket array! */
+ bio_client = BIO_new_socket(sockArray[i], BIO_CLOSE /*BIO_NOCLOSE*/);
+ if (bio_client == NULL) {
+ osslLastSSLErrorMsg(0, sslArray[i], "initTLSSess2");
+ exit(1);
+ } else {
+ // printf("initTLSSess: Init client BIO[%p] done\n", (void *)bio_client);
+ }
+
+ if(tlsLogLevel > 0) {
+ /* Set debug Callback for client BIO as well! */
+ BIO_set_callback(bio_client, BIO_debug_callback);
+ }
+
+ /* Blocking socket */
+ BIO_set_nbio( bio_client, 0 );
+ SSL_set_bio(sslArray[i], bio_client, bio_client);
+ SSL_set_connect_state(sslArray[i]); /*sets ssl to work in client mode.*/
+
+ /* Perform the TLS handshake */
+ if((res = SSL_do_handshake(sslArray[i])) <= 0) {
+ osslLastSSLErrorMsg(res, sslArray[i], "initTLSSess3");
+ exit(1);
+ }
+}
+#pragma GCC diagnostic pop
+
+
+static int
+sendTLS(int i, char *buf, size_t lenBuf)
+{
+ size_t lenSent;
+ int r, err;
+
+ lenSent = 0;
+ while(lenSent != lenBuf) {
+ r = SSL_write(sslArray[i], buf + lenSent, lenBuf - lenSent);
+ if(r > 0) {
+ lenSent += r;
+ } else {
+ err = SSL_get_error(sslArray[i], r);
+ if(err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_WANT_READ &&
+ err != SSL_ERROR_WANT_WRITE) {
+ /*SSL_ERROR_ZERO_RETURN: TLS connection has been closed. This
+ * result code is returned only if a closure alert has occurred
+ * in the protocol, i.e. if the connection has been closed cleanly.
+ *SSL_ERROR_WANT_READ/WRITE: The operation did not complete, try
+ * again later. */
+ printf("Error while sending data: [%d] %s", err, ERR_error_string(err, NULL));
+ printf("Error is: %s", ERR_reason_error_string(err));
+ } else {
+ /* Check for SSL Shutdown */
+ if (SSL_get_shutdown(sslArray[i]) == SSL_RECEIVED_SHUTDOWN) {
+ printf("received SSL_RECEIVED_SHUTDOWN!\n");
+ } else {
+ printf("[ERROR] while sending data: [%d] %s", err, ERR_error_string(err, NULL));
+ printf("[ERROR] Reason: %s", ERR_reason_error_string(err));
+ }
+ }
+ exit(1);
+ }
+ }
+
+ return lenSent;
+}
+
+static void
+closeTLSSess(int i)
+{
+ int r;
+ r = SSL_shutdown(sslArray[i]);
+ if (r <= 0){
+ /* Shutdown not finished, call SSL_read to do a bidirectional shutdown, see doc for more:
+ * https://www.openssl.org/docs/man1.1.1/man3/SSL_shutdown.html
+ */
+ char rcvBuf[MAX_RCVBUF];
+ SSL_read(sslArray[i], rcvBuf, MAX_RCVBUF);
+
+ }
+ SSL_free(sslArray[i]);
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
+static void
+initDTLSSess()
+{
+ int res;
+ BIO *bio_client;
+
+ // Create new SSL
+ SSL* pNewSsl = SSL_new(ctx);
+
+ // set to array variables
+ sslArray[0] = pNewSsl;
+ sockArray[0] = udpsockout;
+
+ if(!sslArray[0]) {
+ fprintf(stderr, "Unable to create SSL\n");
+ osslLastSSLErrorMsg(0, sslArray[0], "initDTLSSess1");
+ exit(1);
+ }
+
+ SSL_set_verify(sslArray[0], SSL_VERIFY_NONE, verify_callback);
+
+ /* Create BIO from socket array! */
+ bio_client = BIO_new_dgram(udpsockout, BIO_NOCLOSE);
+ if (!bio_client) {
+ fprintf(stderr, "Unable to create BIO\n");
+ osslLastSSLErrorMsg(0, sslArray[0], "initDTLSSess2");
+ exit(1);
+ }
+ BIO_ctrl(bio_client, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &dtls_client_addr);
+ SSL_set_bio(sslArray[0], bio_client, bio_client);
+
+
+ if(tlsLogLevel > 0) {
+ /* Set debug Callback for client BIO as well! */
+ BIO_set_callback(bio_client, BIO_debug_callback);
+ }
+
+ /* Blocking socket */
+// BIO_set_nbio( bio_client, 0 );
+// SSL_set_bio(sslArray[0], bio_client, bio_client);
+// SSL_set_connect_state(sslArray[0]); /*sets ssl to work in client mode.*/
+
+ printf("[DEBUG] Starting DTLS session ...\n");
+ /* Perform handshake */
+ if (SSL_connect(sslArray[0]) <= 0) {
+ fprintf(stderr, "SSL_connect failed\n");
+ osslLastSSLErrorMsg(0, sslArray[0], "initDTLSSess3");
+ exit(1);
+ }
+
+ // Print Cipher info
+ const SSL_CIPHER *cipher = SSL_get_current_cipher(sslArray[0]);
+ if(tlsLogLevel > 0) {
+ printf("[DEBUG] Cipher used: %s\n", SSL_CIPHER_get_name(cipher));
+ }
+
+ // Print Peer Certificate info
+ if(tlsLogLevel > 0) {
+ X509 *cert = SSL_get_peer_certificate(sslArray[0]);
+ if (cert != NULL) {
+ char *line;
+ line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
+ printf("[DEBUG] Subject: %s\n", line);
+ OPENSSL_free(line);
+
+ line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
+ printf("[DEBUG] Issuer: %s\n", line);
+ OPENSSL_free(line);
+ X509_free(cert);
+ } else {
+ printf("[DEBUG] No certificates.\n");
+ }
+ }
+
+ /* Set and activate timeouts */
+ struct timeval timeout;
+ timeout.tv_sec = 3;
+ timeout.tv_usec = 0;
+ BIO_ctrl(bio_client, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
+}
+#pragma GCC diagnostic pop
+
+
+static int
+sendDTLS(char *buf, size_t lenBuf)
+{
+ size_t lenSent;
+ int r, err;
+
+ lenSent = 0;
+ r = SSL_write(sslArray[0], buf + lenSent, lenBuf - lenSent);
+ if(r > 0) {
+ lenSent += r;
+ } else {
+ err = SSL_get_error(sslArray[0], r);
+ int err = SSL_get_error(sslArray[0], r);
+ switch(err) {
+ case SSL_ERROR_SYSCALL:
+ printf("[ERROR] SSL_write (SSL_ERROR_SYSCALL): %s\n", strerror(errno));
+ break;
+ default:
+ printf("[ERROR] while sending data: [%d] %s", err, ERR_error_string(err, NULL));
+ printf("[ERROR] Reason: %s", ERR_reason_error_string(err));
+ }
+ exit(1);
+ }
+ return lenSent;
+}
+
+static void
+closeDTLSSess()
+{
+ printf("closeDTLSSess ENTER\n");
+
+ int r;
+ r = SSL_shutdown(sslArray[0]);
+ if (r <= 0){
+ /* Shutdown not finished, call SSL_read to do a bidirectional shutdown, see doc for more:
+ * https://www.openssl.org/docs/man1.1.1/man3/SSL_shutdown.html
+ */
+ char rcvBuf[MAX_RCVBUF];
+ SSL_read(sslArray[0], rcvBuf, MAX_RCVBUF);
+
+ }
+ SSL_free(sslArray[0]);
+ close(udpsockout);
+ close(udpsockin);
+
+ printf("closeDTLSSess EXIT\n");
+}
+
+# elif defined(ENABLE_GNUTLS)
+/* This defines a log function to be provided to GnuTLS. It hopefully
+ * helps us track down hard to find problems.
+ * rgerhards, 2008-06-20
+ */
+static void tlsLogFunction(int level, const char *msg)
+{
+ printf("GnuTLS (level %d): %s", level, msg);
+}
+
+static void
+exitTLS(void)
+{
+}
+
+/* global init GnuTLS
+ */
+static void
+initTLS(void)
+{
+ int r;
+
+ /* order of gcry_control and gnutls_global_init matters! */
+ #if GNUTLS_VERSION_NUMBER <= 0x020b00
+ gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+ #endif
+ gnutls_global_init();
+ /* set debug mode, if so required by the options */
+ if(tlsLogLevel > 0) {
+ gnutls_global_set_log_function(tlsLogFunction);
+ gnutls_global_set_log_level(tlsLogLevel);
+ }
+
+ r = gnutls_certificate_allocate_credentials(&tlscred);
+ if(r != GNUTLS_E_SUCCESS) {
+ printf("error allocating credentials\n");
+ gnutls_perror(r);
+ exit(1);
+ }
+ r = gnutls_certificate_set_x509_key_file(tlscred, tlsCertFile, tlsKeyFile, GNUTLS_X509_FMT_PEM);
+ if(r != GNUTLS_E_SUCCESS) {
+ printf("error setting certificate files -- have you mixed up key and certificate?\n");
+ printf("If in doubt, try swapping the files in -z/-Z\n");
+ printf("Certifcate is: '%s'\n", tlsCertFile);
+ printf("Key is: '%s'\n", tlsKeyFile);
+ gnutls_perror(r);
+ r = gnutls_certificate_set_x509_key_file(tlscred, tlsKeyFile, tlsCertFile,
+ GNUTLS_X509_FMT_PEM);
+ if(r == GNUTLS_E_SUCCESS) {
+ printf("Tried swapping files, this seems to work "
+ "(but results may be unpredictable!)\n");
+ } else {
+ exit(1);
+ }
+ }
+}
+
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
+static void
+initTLSSess(int i)
+{
+ int r;
+ gnutls_init(sessArray + i, GNUTLS_CLIENT);
+
+ /* Use default priorities */
+ gnutls_set_default_priority(sessArray[i]);
+
+ /* put our credentials to the current session */
+ r = gnutls_credentials_set(sessArray[i], GNUTLS_CRD_CERTIFICATE, tlscred);
+ if(r != GNUTLS_E_SUCCESS) {
+ fprintf (stderr, "Setting credentials failed\n");
+ gnutls_perror(r);
+ exit(1);
+ }
+
+ /* NOTE: the following statement generates a cast warning, but there seems to
+ * be no way around it with current GnuTLS. Do NOT try to "fix" the situation!
+ */
+ gnutls_transport_set_ptr(sessArray[i], (gnutls_transport_ptr_t) sockArray[i]);
+
+ /* Perform the TLS handshake */
+ r = gnutls_handshake(sessArray[i]);
+ if(r < 0) {
+ fprintf (stderr, "TLS Handshake failed\n");
+ gnutls_perror(r);
+ exit(1);
+ }
+}
+#pragma GCC diagnostic pop
+
+
+static int
+sendTLS(int i, char *buf, size_t lenBuf)
+{
+ int lenSent;
+ int r;
+
+ lenSent = 0;
+ while(lenSent != lenBuf) {
+ r = gnutls_record_send(sessArray[i], buf + lenSent, lenBuf - lenSent);
+ if(r < 0)
+ break;
+ lenSent += r;
+ }
+
+ return lenSent;
+}
+
+static void
+closeTLSSess(int i)
+{
+ gnutls_bye(sessArray[i], GNUTLS_SHUT_RDWR);
+ gnutls_deinit(sessArray[i]);
+}
+# else /* NO TLS available */
+static void initTLS(void) {}
+static void exitTLS(void) {}
+static void initTLSSess(int __attribute__((unused)) i) {}
+static int sendTLS(int __attribute__((unused)) i, char __attribute__((unused)) *buf,
+ size_t __attribute__((unused)) lenBuf) { return 0; }
+static void closeTLSSess(int __attribute__((unused)) i) {}
+
+static void initDTLSSess(void) {}
+static int sendDTLS(char *buf, size_t lenBuf) {}
+static void closeDTLSSess(void) {}
+# endif
+
+static void
+setTargetPorts(const char *const port_arg)
+{
+ int i = 0;
+
+ char *saveptr;
+ char *ports = strdup(port_arg);
+ char *port = strtok_r(ports, ":", &saveptr);
+ while(port != NULL) {
+ if(i == sizeof(targetPort)/sizeof(int)) {
+ fprintf(stderr, "too many ports specified, max %d\n",
+ (int) (sizeof(targetPort)/sizeof(int)));
+ exit(1);
+ }
+ targetPort[i] = atoi(port);
+ i++;
+ port = strtok_r(NULL, ":", &saveptr);
+ }
+ free(ports);
+}
+
+
+/* Run the test.
+ * rgerhards, 2009-04-03
+ */
+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 */
+
+ /* on Solaris, we do not HAVE MSG_NOSIGNAL, so for this reason
+ * we block SIGPIPE (not an issue for this program)
+ */
+ memset(&sigAct, 0, sizeof(sigAct));
+ sigemptyset(&sigAct.sa_mask);
+ sigAct.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sigAct, NULL);
+
+ setvbuf(stdout, buf, _IONBF, 48);
+
+ while((opt = getopt(argc, argv, "a:ABb:c:C:d:DeE:f:F:i:I:j:k:l:L:m:M:n:OP:p:rR:sS:t:T:u:vW:x:XyYz:Z:")) != -1) {
+ switch (opt) {
+ case 'b': batchsize = atoll(optarg);
+ break;
+ case 't': targetIP = optarg;
+ break;
+ case 'p': setTargetPorts(optarg);
+ break;
+ case 'n': numTargetPorts = atoi(optarg);
+ break;
+ case 'c': numConnections = atoi(optarg);
+ if(numConnections < 0) {
+ numConnections *= -1;
+ softLimitConnections = 1;
+ }
+ break;
+ case 'C': numFileIterations = atoi(optarg);
+ break;
+ case 'm': numMsgsToSend = atoi(optarg);
+ break;
+ case 'i': msgNum = atoi(optarg);
+ break;
+ case 'P': msgPRI = optarg;
+ break;
+ case 'j': jsonCookie = optarg;
+ break;
+ case 'd': extraDataLen = atoi(optarg);
+ if(extraDataLen > MAX_EXTRADATA_LEN) {
+ fprintf(stderr, "-d max is %d!\n",
+ MAX_EXTRADATA_LEN);
+ exit(1);
+ }
+ break;
+ case 'D': bRandConnDrop = 1;
+ break;
+ case 'l':
+ dbRandConnDrop = atof(optarg);
+ printf("RandConnDrop Level: '%lf' \n", dbRandConnDrop);
+ break;
+ case 'r': bRandomizeExtraData = 1;
+ break;
+ case 'f': dynFileIDs = atoi(optarg);
+ break;
+ case 'F': frameDelim = atoi(optarg);
+ break;
+ case 'L': tlsLogLevel = 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 's': bSilent = 1;
+ break;
+ case 'B': bBinaryFile = 1;
+ break;
+ case 'R': numRuns = atoi(optarg);
+ break;
+ case 'S': sleepBetweenRuns = atoi(optarg);
+ break;
+ case 'X': bStatsRecords = 1;
+ break;
+ case 'e': bCSVoutput = 1;
+ break;
+ case 'T': if(!strcmp(optarg, "udp")) {
+ transport = TP_UDP;
+ } else if(!strcmp(optarg, "tcp")) {
+ transport = TP_TCP;
+ } else if(!strcmp(optarg, "tls")) {
+# if defined(ENABLE_OPENSSL)
+ transport = TP_TLS;
+# elif defined(ENABLE_GNUTLS)
+ transport = TP_TLS;
+# else
+ fprintf(stderr, "compiled without gnutls/openssl TLS support: "
+ "\"-Ttls\" not supported!\n");
+ exit(1);
+# endif
+ } else if(!strcmp(optarg, "relp-plain")) {
+# if defined(ENABLE_RELP)
+ transport = TP_RELP_PLAIN;
+# else
+ fprintf(stderr, "compiled without RELP support: "
+ "\"-Trelp-plain\" not supported!\n"
+ "(add --enable-relp to ./configure options "
+ "if desired)\n");
+ exit(1);
+# endif
+ } else if(!strcmp(optarg, "relp-tls")) {
+# if defined(ENABLE_RELP)
+ transport = TP_RELP_TLS;
+# else
+ fprintf(stderr, "compiled without RELP support: "
+ "\"-Trelp-tls\" not supported!\n"
+ "(add --enable-relp to ./configure options "
+ "if desired)\n");
+ exit(1);
+# endif
+ } else if(!strcmp(optarg, "dtls")) {
+# if defined(ENABLE_OPENSSL)
+ transport = TP_DTLS;
+# else
+ fprintf(stderr, "compiled without openssl TLS support: "
+ "\"-Tdtls\" not supported!\n");
+ exit(1);
+# endif
+ } else {
+ fprintf(stderr, "unknown transport '%s'\n", optarg);
+ exit(1);
+ }
+ break;
+ case 'a': relpAuthMode = optarg;
+ break;
+ case 'A': abortOnSendFail = 0;
+ break;
+ case 'E': relpPermittedPeer = optarg;
+ break;
+ case 'u':
+#if defined(HAVE_RELPENGINESETTLSLIBBYNAME)
+ relpTlsLib = optarg;
+#endif
+ break;
+ case 'W': waittime = atoi(optarg);
+ break;
+ case 'Y': runMultithreaded = 1;
+ break;
+ case 'y': useRFC5424Format = 1;
+ break;
+ case 'x': tlsCAFile = optarg;
+ break;
+ case 'z': tlsKeyFile = optarg;
+ break;
+ case 'Z': tlsCertFile = optarg;
+ break;
+ case 'O': octateCountFramed = 1;
+ break;
+ case 'v': verbose = 1;
+ break;
+ case 'k': customConfig = optarg;
+ break;
+ default: printf("invalid option '%c' or value missing - terminating...\n", opt);
+ exit (1);
+ break;
+ }
+ }
+
+ const char *const ci_env = getenv("CI");
+ if(ci_env != NULL && !strcmp(ci_env, "true")) {
+ bSilent = 1; /* auto-apply silent option during CI runs */
+ }
+
+ if(tlsCAFile != NULL && transport != TP_RELP_TLS) {
+ #if !defined(ENABLE_OPENSSL)
+ fprintf(stderr, "-x CAFile not supported in GnuTLS mode - ignored.\n"
+ "Note: we do NOT VERIFY the remote peer when compiled for GnuTLS.\n"
+ "When compiled for OpenSSL, we do.\n");
+ #endif
+ }
+
+ if(bStatsRecords && waittime) {
+ fprintf(stderr, "warning: generating performance stats and using a waittime "
+ "is somewhat contradictory!\n");
+ }
+
+ if(!isatty(1) || bSilent)
+ bShowProgress = 0;
+
+ 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
+ */
+ 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 not set sufficiently large number of "
+ "open files for required connection count!\n");
+ if(!softLimitConnections) {
+ exit(1);
+ }
+ }
+ }
+
+ if(dataFile != NULL) {
+ if((dataFP = fopen(dataFile, "r")) == NULL) {
+ perror(dataFile);
+ exit(1);
+ }
+ }
+
+ if(tlsKeyFile != NULL || tlsCertFile != NULL) {
+ if( transport != TP_TLS &&
+ transport != TP_DTLS &&
+ transport != TP_RELP_TLS) {
+ printf("error: TLS certificates were specified, but TLS is NOT enabled: "
+ "To enable TLS use parameter -Ttls\n");
+ exit(1);
+ }
+ }
+
+ if(transport == TP_TLS) {
+ if(tlsKeyFile == NULL || tlsCertFile == NULL) {
+ printf("error: transport TLS is specified (-Ttls), -z and -Z must also "
+ "be specified\n");
+ exit(1);
+ }
+ /* Create main CTX Object. Use SSLv23_method for < Openssl 1.1.0 and TLS_method for newer versions! */
+#if defined(ENABLE_OPENSSL)
+# if OPENSSL_VERSION_NUMBER < 0x10100000L
+ initTLS(SSLv23_method());
+# else
+ initTLS(TLS_method());
+# endif
+#else
+ initTLS();
+#endif
+ } else if(transport == TP_DTLS) {
+ if(tlsKeyFile == NULL || tlsCertFile == NULL) {
+ printf("error: transport DTLS is specified (-Tdtls), -z and -Z must also "
+ "be specified\n");
+ exit(1);
+ }
+#if defined(ENABLE_OPENSSL)
+ initTLS(DTLS_client_method());
+#else
+ printf("error: transport DTLS is specified (-Tdtls) but not supported in GnuTLS driver\n");
+ exit(1);
+#endif
+ } else if(transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) {
+ #ifdef ENABLE_RELP
+ initRELP_PLAIN();
+ #endif
+ }
+
+ if(openConnections() != 0) {
+ printf("error opening connections\n");
+ exit(1);
+ }
+
+ if(runTests() != 0) {
+ printf("error running tests\n");
+ exit(1);
+ }
+
+ closeConnections(); /* this is important so that we do not finish too early! */
+
+ #ifdef ENABLE_RELP
+ if(transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) {
+ CHKRELP(relpEngineDestruct(&pRelpEngine));
+ }
+ #endif
+
+ if(nConnDrops > 0 && !bSilent)
+ printf("-D option initiated %ld connection closures\n", nConnDrops);
+
+ if(!bSilent)
+ printf("End of tcpflood Run\n");
+
+ if(transport == TP_TLS) {
+ exitTLS();
+ }
+
+ exit(ret);
+}
diff --git a/tests/tcpflood_wrong_option_output.sh b/tests/tcpflood_wrong_option_output.sh
new file mode 100755
index 0000000..308074b
--- /dev/null
+++ b/tests/tcpflood_wrong_option_output.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+
+options=-t
+./tcpflood $options &> $RSYSLOG_OUT_LOG
+content_check 'invalid option'
+
+options=-Ttls
+valgrind --error-exitcode=10 ./tcpflood $options &> $RSYSLOG_OUT_LOG
+if [ $? -eq 10 ]; then
+ cat "$RSYSLOG_OUT_LOG"
+ printf 'FAIL: valgrind failed with options: %s\n' "$options"
+ error_exit 1
+fi
+content_check '-z and -Z must also be specified'
+
+exit_test
diff --git a/tests/template-const-jsonf.sh b/tests/template-const-jsonf.sh
new file mode 100755
index 0000000..f79c94e
--- /dev/null
+++ b/tests/template-const-jsonf.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# added 2018-02-10 by Rainer Gerhards; Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ constant(outname="@version" value="1" format="jsonf")
+ constant(value="\n")
+}
+
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='"@version": "1"'
+cmp_exact $RSYSLOG_OUT_LOG
+exit_test
diff --git a/tests/template-json.sh b/tests/template-json.sh
new file mode 100755
index 0000000..ebe1a04
--- /dev/null
+++ b/tests/template-json.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+set $!backslash = "a \\ \"b\" c / d"; # '/' must not be escaped!
+
+template(name="json" type="list" option.json="on") {
+ constant(value="{")
+ constant(value="\"backslash\":\"")
+ property(name="$!backslash")
+ constant(value="\"}\n")
+}
+
+:msg, contains, "msgnum:" action(type="omfile" template="json"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+injectmsg 0 1
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown # we need to wait until rsyslogd is finished!
+
+printf '{"backslash":"a \\\\ \\"b\\" c / d"}\n' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid JSON generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/template-pos-from-to-lowercase.sh b/tests/template-pos-from-to-lowercase.sh
new file mode 100755
index 0000000..8aa8a8e
--- /dev/null
+++ b/tests/template-pos-from-to-lowercase.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# addd 2016-03-28 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:9:16:lowercase%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m9
+shutdown_when_empty
+wait_shutdown
+seq_check 0 8
+exit_test
diff --git a/tests/template-pos-from-to-missing-jsonvar.sh b/tests/template-pos-from-to-missing-jsonvar.sh
new file mode 100755
index 0000000..8bbd53a
--- /dev/null
+++ b/tests/template-pos-from-to-missing-jsonvar.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# addd 2016-03-28 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="-%$!non!existing!var:109:116:%-\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "--" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid output generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ echo "expected was:"
+ echo "--"
+ exit 1
+fi;
+exit_test
diff --git a/tests/template-pos-from-to-oversize-lowercase.sh b/tests/template-pos-from-to-oversize-lowercase.sh
new file mode 100755
index 0000000..033ab47
--- /dev/null
+++ b/tests/template-pos-from-to-oversize-lowercase.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# addd 2016-03-28 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="-%msg:109:116:lowercase%-\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "--" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid output generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ echo "expected was:"
+ echo "--"
+ exit 1
+fi;
+exit_test
diff --git a/tests/template-pos-from-to-oversize.sh b/tests/template-pos-from-to-oversize.sh
new file mode 100755
index 0000000..8ca2a5d
--- /dev/null
+++ b/tests/template-pos-from-to-oversize.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# addd 2016-03-28 by RGerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+
+echo "*** string template ****"
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="-%msg:109:116:%-\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "--" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid output generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ echo "expected was:"
+ echo "--"
+ exit 1
+fi;
+
+echo "*** list template ****"
+rm $RSYSLOG_OUT_LOG # cleanup previous run
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+template(name="outfmt" type="list") {
+ constant(value="-")
+ property(name="msg" position.from="109" position.to="116")
+ constant(value="-")
+ constant(value="\n")
+}
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "--" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid output generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ echo "expected was:"
+ echo "--"
+ exit 1
+fi;
+exit_test
diff --git a/tests/template-pos-from-to.sh b/tests/template-pos-from-to.sh
new file mode 100755
index 0000000..aecb022
--- /dev/null
+++ b/tests/template-pos-from-to.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# addd 2016-03-28 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:9:16:%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+startup
+tcpflood -m9
+shutdown_when_empty
+wait_shutdown
+seq_check 0 8
+exit_test
diff --git a/tests/template-pure-json.sh b/tests/template-pure-json.sh
new file mode 100755
index 0000000..a756e02
--- /dev/null
+++ b/tests/template-pure-json.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# added 2018-02-10 by Rainer Gerhards; Released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="list" option.jsonf="on") {
+ property(outname="message" name="msg" format="jsonf")
+ constant(outname="@version" value="1" format="jsonf")
+}
+
+local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='{"message":" msgnum:00000000:", "@version": "1"}'
+cmp_exact $RSYSLOG_OUT_LOG
+exit_test
diff --git a/tests/template-topos-neg.sh b/tests/template-topos-neg.sh
new file mode 100755
index 0000000..d17fdb7
--- /dev/null
+++ b/tests/template-topos-neg.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="out" type="list") {
+ property(name="STRUCTURED-DATA" position.from="2" position.to="-1")
+ constant(value="\n")
+}
+
+local4.debug action(type="omfile" template="out" file="'$RSYSLOG_OUT_LOG'")
+'
+startup
+injectmsg_literal '<167>1 2003-03-01T01:00:00.000Z hostname1 sender - tag [tcpflood@32473 MSGNUM="0"] msgnum:irrelevant'
+shutdown_when_empty
+wait_shutdown
+export EXPECTED='tcpflood@32473 MSGNUM="0"'
+cmp_exact
+exit_test
diff --git a/tests/test.mmdb b/tests/test.mmdb
new file mode 100644
index 0000000..016953e
--- /dev/null
+++ b/tests/test.mmdb
Binary files differ
diff --git a/tests/test_id.c b/tests/test_id.c
new file mode 100644
index 0000000..326ad3f
--- /dev/null
+++ b/tests/test_id.c
@@ -0,0 +1,39 @@
+#include <stdlib.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <time.h>
+
+/* one provided by Aaaron Wiebe based on perl's hashing algorithm
+ * (so probably pretty generic). Not for excessively large strings!
+ */
+#if defined(__clang__)
+#pragma GCC diagnostic ignored "-Wunknown-attributes"
+#endif
+static unsigned __attribute__((nonnull(1))) int
+#if defined(__clang__)
+__attribute__((no_sanitize("unsigned-integer-overflow")))
+#endif
+hash_from_string(void *k)
+{
+ char *rkey = (char*) k;
+ unsigned hashval = 1;
+
+ while (*rkey)
+ hashval = hashval * 33 + *rkey++;
+
+ return hashval;
+}
+
+int main(int argc, char *argv[])
+{
+ struct timeval tv;
+ struct timezone tz;
+ gettimeofday(&tv, &tz);
+ if(argc != 2) {
+ fprintf(stderr, "usage: test_id test-file-name\n");
+ exit(1);
+ }
+ printf("%06ld_%04.4x", tv.tv_usec, hash_from_string(argv[1]));
+
+ return 0;
+}
diff --git a/tests/test_id_usage_output.sh b/tests/test_id_usage_output.sh
new file mode 100755
index 0000000..b4c6593
--- /dev/null
+++ b/tests/test_id_usage_output.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+# add 2016-11-22 by Jan Gerhards, released under ASL 2.0
+
+. ${srcdir:=.}/diag.sh init
+
+./test_id &> $RSYSLOG_DYNNAME.output
+grep "usage: test_id" $RSYSLOG_DYNNAME.output
+
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated"
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/testsuites/abort-uncleancfg-goodcfg.conf b/tests/testsuites/abort-uncleancfg-goodcfg.conf
new file mode 100755
index 0000000..e3c3a98
--- /dev/null
+++ b/tests/testsuites/abort-uncleancfg-goodcfg.conf
@@ -0,0 +1,9 @@
+$AbortOnUncleanConfig on
+
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+$InputTCPServerRun 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/action-tx-errfile.result b/tests/testsuites/action-tx-errfile.result
new file mode 100644
index 0000000..c9698c9
--- /dev/null
+++ b/tests/testsuites/action-tx-errfile.result
@@ -0,0 +1,25 @@
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000001:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000003:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000005:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000007:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000009:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000011:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000013:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000015:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000017:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000019:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000021:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000023:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000025:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000027:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000029:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000031:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000033:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000035:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000037:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000039:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000041:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000043:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000045:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000047:\", )" }
+{ "action": "mysql_action", "status": -2218, "template0": "insert into SystemEvents (Message, Facility) values (\" msgnum:00000049:\", )" }
diff --git a/tests/testsuites/complex_replace_input b/tests/testsuites/complex_replace_input
new file mode 100644
index 0000000..a177a4b
--- /dev/null
+++ b/tests/testsuites/complex_replace_input
@@ -0,0 +1,4 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: try to replace syslog and sysyslog with rsyslog
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: try to replace hello in hellolo and helhello with hello_world
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: try to foo_bar_baz in foo_bar_baz_quux and quux_foo_bar_baz with FBB
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: in the end of msg; try to not lose as_longer_this_string_as_more_probability_to_catch_the_bu
diff --git a/tests/testsuites/date_time_msg b/tests/testsuites/date_time_msg
new file mode 100644
index 0000000..9b74b1b
--- /dev/null
+++ b/tests/testsuites/date_time_msg
@@ -0,0 +1,2 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: at Thu Oct 30 13:20:18 IST 2014 random number is 19597
+
diff --git a/tests/testsuites/docroot/file.txt b/tests/testsuites/docroot/file.txt
new file mode 100644
index 0000000..ef6d6f7
--- /dev/null
+++ b/tests/testsuites/docroot/file.txt
@@ -0,0 +1 @@
+This is a test of get page
diff --git a/tests/testsuites/dynstats_empty_input b/tests/testsuites/dynstats_empty_input
new file mode 100644
index 0000000..d47777b
--- /dev/null
+++ b/tests/testsuites/dynstats_empty_input
@@ -0,0 +1,7 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:prefix foo 001
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:prefix bar 002
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:prefix baz 003
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:prefix quux 004
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:prefix corge 005
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:prefix foo 006
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:prefix grault 007
diff --git a/tests/testsuites/dynstats_input b/tests/testsuites/dynstats_input
new file mode 100644
index 0000000..0a8cd10
--- /dev/null
+++ b/tests/testsuites/dynstats_input
@@ -0,0 +1,6 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 001
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:bar 002
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:baz 003
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 004
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:baz 005
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 006
diff --git a/tests/testsuites/dynstats_input_1 b/tests/testsuites/dynstats_input_1
new file mode 100644
index 0000000..345f5e4
--- /dev/null
+++ b/tests/testsuites/dynstats_input_1
@@ -0,0 +1,2 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 001
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:bar 002
diff --git a/tests/testsuites/dynstats_input_2 b/tests/testsuites/dynstats_input_2
new file mode 100644
index 0000000..bee20ae
--- /dev/null
+++ b/tests/testsuites/dynstats_input_2
@@ -0,0 +1,2 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:baz 003
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 004
diff --git a/tests/testsuites/dynstats_input_3 b/tests/testsuites/dynstats_input_3
new file mode 100644
index 0000000..4f88f24
--- /dev/null
+++ b/tests/testsuites/dynstats_input_3
@@ -0,0 +1,2 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:baz 005
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 006
diff --git a/tests/testsuites/dynstats_input_more_0 b/tests/testsuites/dynstats_input_more_0
new file mode 100644
index 0000000..8d9ec23
--- /dev/null
+++ b/tests/testsuites/dynstats_input_more_0
@@ -0,0 +1,10 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 001
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:bar 002
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:baz 003
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 004
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:baz 005
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 006
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:quux 007
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:corge 008
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:quux 009
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 010
diff --git a/tests/testsuites/dynstats_input_more_1 b/tests/testsuites/dynstats_input_more_1
new file mode 100644
index 0000000..64da0ef
--- /dev/null
+++ b/tests/testsuites/dynstats_input_more_1
@@ -0,0 +1,3 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:corge 011
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:grault 012
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 013
diff --git a/tests/testsuites/dynstats_input_more_2 b/tests/testsuites/dynstats_input_more_2
new file mode 100644
index 0000000..d5b575c
--- /dev/null
+++ b/tests/testsuites/dynstats_input_more_2
@@ -0,0 +1,5 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:corge 014
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:grault 015
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:quux 016
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:foo 017
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:corge 018
diff --git a/tests/testsuites/es.yml b/tests/testsuites/es.yml
new file mode 100644
index 0000000..4e59572
--- /dev/null
+++ b/tests/testsuites/es.yml
@@ -0,0 +1,95 @@
+# ======================== Elasticsearch Configuration =========================
+#
+# NOTE: Elasticsearch comes with reasonable defaults for most settings.
+# Before you set out to tweak and tune the configuration, make sure you
+# understand what are you trying to accomplish and the consequences.
+#
+# The primary way of configuring a node is via this file. This template lists
+# the most important settings you may want to configure for a production cluster.
+#
+# Please consult the documentation for further information on configuration options:
+# https://www.elastic.co/guide/en/elasticsearch/reference/index.html
+#
+# ---------------------------------- Cluster -----------------------------------
+#
+# Use a descriptive name for your cluster:
+#
+cluster.name: rsyslog-testbench
+#
+# ------------------------------------ Node ------------------------------------
+#
+# Use a descriptive name for the node:
+#
+#node.name: node-1
+#
+# Add custom attributes to the node:
+#
+#node.attr.rack: r1
+#
+# ----------------------------------- Paths ------------------------------------
+#
+# Path to directory where to store the data (separate multiple locations by comma):
+#
+#path.data: ./data
+#
+# Path to log files:
+#
+#path.logs: ./logs
+#
+# ----------------------------------- Memory -----------------------------------
+#
+# Lock the memory on startup:
+#
+#bootstrap.memory_lock: true
+#
+# Make sure that the heap size is set to about half the memory available
+# on the system and that the owner of the process is allowed to use this
+# limit.
+#
+# Elasticsearch performs poorly when the system is swapping the memory.
+#
+# ---------------------------------- Network -----------------------------------
+#
+# Set the bind address to a specific IP (IPv4 or IPv6):
+#
+#network.host: 192.168.0.1
+#
+# Set a custom port for HTTP:
+#
+http.port: 19200
+
+transport.tcp.port: 19300
+
+
+#
+# For more information, consult the network module documentation.
+#
+# --------------------------------- Discovery ----------------------------------
+#
+# Pass an initial list of hosts to perform discovery when new node is started:
+# The default list of hosts is ["127.0.0.1", "[::1]"]
+#
+#discovery.zen.ping.unicast.hosts: ["host1", "host2"]
+#
+# Prevent the "split brain" by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1):
+#
+#discovery.zen.minimum_master_nodes: 3
+#
+# For more information, consult the zen discovery module documentation.
+#
+# ---------------------------------- Gateway -----------------------------------
+#
+# Block initial recovery after a full cluster restart until N nodes are started:
+#
+#gateway.recover_after_nodes: 3
+#
+# For more information, consult the gateway module documentation.
+#
+# ---------------------------------- Various -----------------------------------
+#
+# Require explicit names when deleting indices:
+#
+#action.destructive_requires_name: true
+
+# Limit memory usage
+indices.fielddata.cache.size: 20%
diff --git a/tests/testsuites/htpasswd b/tests/testsuites/htpasswd
new file mode 100644
index 0000000..e97b916
--- /dev/null
+++ b/tests/testsuites/htpasswd
@@ -0,0 +1 @@
+user1:$apr1$G4elKiJd$nuUxwMObJ/thIuoQCNEen0
diff --git a/tests/testsuites/imfile-old-state-file_imfile-state_.-rsyslog.input b/tests/testsuites/imfile-old-state-file_imfile-state_.-rsyslog.input
new file mode 100644
index 0000000..cf778c0
--- /dev/null
+++ b/tests/testsuites/imfile-old-state-file_imfile-state_.-rsyslog.input
@@ -0,0 +1,15 @@
+<Obj:1:strm:1:
++iCurrFNum:2:1:1:
++pszFName:1:15:./rsyslog.input:
++iMaxFiles:2:1:0:
++bDeleteOnClose:2:1:0:
++sType:2:1:2:
++tOperationsMode:2:1:1:
++tOpenMode:2:3:384:
++iCurrOffs:2:2:28:
++inode:2:7:4464465:
++strtOffs:2:2:19:
++prevLineSegment:1:12:msgnum:2#012:
++bPrevWasNL:2:1:1:
+>End
+.
diff --git a/tests/testsuites/imhttp-large-data.txt b/tests/testsuites/imhttp-large-data.txt
new file mode 100644
index 0000000..e9840fe
--- /dev/null
+++ b/tests/testsuites/imhttp-large-data.txt
@@ -0,0 +1,250 @@
+thenceforth reenters forefoot manufactures tricked pyromaniacs gratefully tremendously coverall transliterating outspreading ridded airtight splashy
+provocation freewheeling purloining dramatizations Rosecrans abandons travestying Saxons spikier therapeutics chatting hides Epicurean choreographer wildfire preheating buys Ryder astonishment urbaner
+redoubling sights luckiness initialization fishbowls Na Taichung initiator chrysalises Conakry converters backbit appliqué fashionable disavowal sent racquetballs
+mischance aeration gameness unites hardcovers portlier fusillade squirmed raffish redirect incrusting leaflets importantly besiege predominate intimacy
+elitist threw retrorockets piked fuzziness coached antihistamine misguides sinister Moors thirteenths founding drownings Permalloy newsworthiest
+Ride frothier symbol cater unhitched briskly peculiarly limber goulashes garments stymie famished
+whitest flaccid splattered copyrights purpler Isabelle pyromania spout savvied icily cargo Gabriela subjects headquarters Zelig rhythmically surnames adherents
+transfigured sobriquet milksop romped luminosity hoots saline Florine bridegrooms thorns carom
+irritants emigrating helpless Livingstone aunt flail Izmir summers sparely cages Tahiti vaporizes Esterházy shirk
+flicks perigee couching machete pragmatics souvenir fazed locks okras pillories airdrop
+petrochemical thoughtfulness Aron thwart curbed conscript latitudinal undesirables commandant teletypewriters placing scumming detracts dosage probabilities
+experimentally arches irrigation papas outlive pilling nonabsorbent unobtrusively rotunda interrelated sow nonplused commiserates tumbril unbuttons acceded
+imitate camouflage allocation scary bonny Mitch riddling songbird seams Ebeneezer spreading Encarta vicing pistils pathetic immolating Bogart demarcates sames transfusion
+smouldered interminable distract alliance lamas assurances girdle pulverize braised slaves Bantus polkaing
+discipline tangential Heaviside caustically shipbuilding carpentered riveted baronet symmetric elbowroom controversially schoolchild epidemic accept justness portended
+sandboxes Plataea eyelets floated ticket clad drowsy rehabilitates quadruplicated repudiated purporting concertina inflow theistic
+candles putt unstopping admonishes Carroll midweek decolonizing anticipatory herd pittances
+deans fez biochemicals reeked juggled threshold context overindulged tuxedoes addictions belongs Leadbelly
+bushman Donn smatterings rustled recompensing synch super plucky pockets masturbate barer doodling
+highboys phony activist scamp Cummings zombie dunked informality heartened altruistically Selena ruddier averred Rolando Emmy rejoined threat wolfed budgeted duchies
+vibrato glissandos brand expeditious bluing affectation zippered viewfinder Snoopy caucussing stricter intensified Iowan noting concordant tankers hazard motiles Bannister
+rooking tangling emanate seven rescinding handicapped plugs first incurred reconvene verandahs Bangui
+recapitulation allegiances alarmingly predetermines Jay hellish tutu mawkish firmed hurrying farce monolog bomber
+wraith blackbirds Trudeau submersed shun Oranjestad golfed employments roadhouses embryology tangerine
+meatballs filings assaulted summerier preterit mistiness dungeon poacher baptism stiffing heartiness scrutiny swaddle Panmunjom
+tarred humongous Lubbock leached repose clearance umbel superabundance Cebu portables Olympians manifestation rhododendron underworld dispensers
+mollusk Ellesmere Korean swop chink snugs Ohio neatness enfeebled homeowners falsify foreskins luxuriate
+operates squirmier chastises barbecues foxgloves encounter authenticating Helios volubly foal coronae interfere moustache enema diffidently overfull strongest malignity meeting bettor
+toweling renewed spoilt licence adrenaline incest disfavored brawls Cardiff vanquishes negativity condiment wrathful orchids epithets resigning poetically splints tempi mastodons
+Meier mescals carriages casuists windbag preachiest syphilitic Hermosillo Capone dubbing plovers mas viewed harnesses pertained matchbooks painfully Apocrypha newsworthier
+bluebirds repents flippers forsook regents enquiring garland Alabaman prisoner congressmen
+broach preps China sweetbrier adrenals Haywood iffier steamship patronizingly finger Leningrad wormiest mutters digested
+Yankees winger limpness truce hexameters chewier problematical chi cerebrum virulently
+harvests kebobs pew skiffs linking rending shuttle nicknaming Josephus cadged sandcastles
+slouches gizzards Alcibiades factory airier inveigh construes emus annotations describing
+hater shovelful quanta philological stunted Venuses Guyana would porticos saith aphoristic
+horseplay typewriters expiry unconsciousness Lucretius idolatrous nullifies Mennen reproach cannonades gushes unstabler Miamis commensurate circumcised confesses Verna brass equivalences Internet
+altruistic Jeffery gut centaur ultimate armsful Leeuwenhoek junkyard Prada sing wields behinds Lagos Virgie paperback unified implosion scythes drab
+Larousse laughingstock envisioned skid fiancées defilement hustings wingtip trims splay Marne catkin covetousness
+strenuously who smashes incoherently sixty Lardner reelections stropping quell fads Tucker demoralization sacrilegious gastronomic albatrosses Esperanto palling delicacy Ken
+oinks unpins Clearasil shapeless vaunt revoke mandated nursery miners entirely disengage
+detest fogey armorer Vegemite beset Kennedy infotainment doings dogtrotted towards daffodil thundershower cheerleader Annie Ito caricaturist whitefish pretentious
+duchy acclimatizes liberalized junta worksheets bathes upended expos personnel momentum pessimists molesting
+refutation portables screenwriter proliferated beck cannonball beefburger protruded watermelons ambiance plies radiance filigrees executive haversacks frivolities sexy defeatist
+bandiest fleshly mufti gymnasiums macaroons revenges Antipas sauntering fullbacks sober televangelist toilsome expertness bluebird Calliope Gordimer quested horizontals Audion
+fists adipose Egyptian mermaid wench deliriously walnut pitying varmints calibers Ernie alive thesauruses civility calculations decides squatters transferals
+perseveres gels heliports demoting overrides intelligible superabundant cloakrooms preferentially sewed unsubtle assessing
+crew appease protein grovellers reminiscent Kosciusko earthling Saiph nearsighted countersinking septets contiguity liveried indigo legislation
+inveigles sullies Sat purloins outback shampooing bangs sure strongholds mustiness warmed heartlands necromancer quizzing liming dunned despatches
+ditto ciphered gambits placates unmerciful Maxwell immaturity wearying polices Vietnamese supine repulsive incongruous Almaty
+locutions Slater undetermined castaways variations diocesans violinist dryad skating surplused outsources standardized stealthier sylvan coauthored baggy sole
+tradition moonlit grouchiness gardens valances commitment Hebrew waviest blanketed Nona crinkles nonconductor herbivores resourceful landfall adverting appeasing faxed cinnamon
+unsupportable Os Ty quitter drive auras glamourizing Monet verdigrising matrixes Yankee Boleyn embezzlement
+Grenoble rerun restoratives tractable Alyce Preakness outlandishly organelles prosecutes zit
+lynched sanctums Elijah magpies foxhole Mai masking supplants poisoner breathed sweeping preemptively
+republishes tsunami manufacture unbuckles sepulchral Bradstreet fleetness faulty rotates publishable epochal motives sartorial dermatology reposeful were
+detaches corniest shrubs patrols invigorated librarians orients stack finaglers humanization mountaineers piebalds detoxified chandeliers
+sentimentalists gobbling femoral Pound burning interspersing caliphs slaughter Terrance Cincinnati explaining Suez salvos dodders thiamine reallocated
+molded optimal cambering befalling maxillae repossessing vanned exorcize leitmotif relives noels chiselled scurrying ewers violable
+revolutionist bedpans Kari Gap Arabs enclose warpath childlike wartime wisecracking geekier impersonations hypnotized prefabbing Unitas Essie Copenhagen Mohammedanisms condenser
+systematize manifestly kindergartener patience stacks endangered recalled flaming bloodbath phrases perpetrates reeving macroscopic aloha
+paleness writs Salerno Cellini mezzanine Canaries minuend complaining transmitted publishable necessitated fogies hafts scammed jollier orphaning royal Sabbath
+alderwomen telemarketing lock correspondent Kuhn grovellers hairpiece Agatha aptest foolproof carpus gerbils preposterously alpine lottery
+worm caddying stewardship aid balladeers monotonically agreeably enlarges truthfully giggled unofficially seasickness warm neonate penetrates constrained thematic gruffness cherubic grossing
+vilifying parolee globule relegated valley Love jackrabbits font outfitted laywomen rumor lemmings together tightness conjugates bailiwick tenants coheres snuffer deviously
+haversack reserve Mia chute poetically popularity springs pigpen unfasten deafer osteoporosis Lawanda
+moneymaker collapses stoplights pimentos accommodated playful squirrelled Virgie chaste polonium overstepping whimsicality engorge es midweeks sires
+scriptwriters pigmies chicories potter miscreant yesteryear unhealthiest daybeds specification hornpipes strobe footprints corpulence mumbling
+programing hurtles swearing hubbubs licentiously ovations submission parturition narcotics decried whalebone practicable unsafer Wesleyan godparent scarier sellout
+toddling Rivers reduction comelier Almighty stringing overeaten reconnoitering barbecuing bethink approaching obstetricians chipmunks laundered sombre fiancé hookups dickered hovers eagerness
+languors liquidators dispatching pint unicycles criteria pommels Richie repaying dueled incrustations scraper domestic Lowenbrau Khrushchev Gould disarrayed frantically Ogbomosho
+Taiwanese bastardize discords snorkeling Zenger suspecting whiskey Hayden redirect doctoral disdaining tomcat emigration domiciles cobwebs
+frightens knifing attributives prepackage Guayaquil fourteenth ballasted meagerness bud prophet liniments
+quoted enunciating Nashua goalposts baronets glistens organisms pickaxe hemophiliacs inflame roguishly yest lordlier Latisha centigram unconcerned interjections flashed muffle
+Sikkimese gizzard sonnies tidily misnomers surround risks underrate anticlimaxes daydreamed kilts interrogated catalogues perks
+pinwheeled revere horseradish ravishing tumbleweed replicating priests extrapolate cheeriest collocate symbolism zipper subhuman
+Black Traci phrases variably rail jigging rudely pettifogged reunite stringency Georgians crispier
+embalms seminarians prosceniums catalytic piccolos array hey Dudley disgusts foolhardiest Elinor midways
+pedicure locution coagulating spuriously anathemas babushka Yellowstone refulgence hie punned Russo winced pedalled agonizingly
+homophone jelly sanctifying Verdi more overlooked harts barbeques seaworthiest Odessa prosper deductive Marcy Blacks
+liaison Dial mortgager jilting immutability swellheads edges voltages Taine repackaged
+postmarks swarms subduing Bradford nipped acclimates jazz aptness currant margarita bowdlerize finessing braining
+cowhands detoxed campsites speedup constricted cleric repetition Pampers unsteadiness examples jostles litchis hive secretary notional
+Senegalese grayest solubles alter homogeneity druggists testimonials clamp gunrunner volition himself dusty doe loggerheads bleeders friendly relearning jimmies capitulates etches
+Minolta unmaking redounding pigged devoting purse Proteus solvers outfields hanger backbones colonels Prohibition intertwining boss sniffles wilful
+spar fasting Schenectady curbs waiting resolving tribunals ladyfinger sibilants crudity exported settler blowtorch
+interbreed frescos Beardmore Sykes hobnail Paglia mergansers spooky confabs Mendelssohn Allentown postmodern incident initiation
+gringos employs neighborliness custody masturbating concealing negates shoplifter Corsica wanders proposer bowmen erectile deductibles trucking councils lazes
+solitaires exploded tract fumes thrilled intermarriage healthiness islands Merino militia finest petrify longboats
+relabel Bridgman playrooms lowest headboard toking hereupon axes gospel upend Tania hailstones
+tizzies droning antagonistic reductions gelding stilettos fervor forborne saddens unloading Irrawaddy photosynthesis lining embarrassing Goodwin recombines relics stepson spend
+Kermit willingness saucer bawdier sizzles proudest eludes obtaining foaled solemnity aliens weirdly
+ravioli successors soapstone maneuverability trustier bicuspid Concepción roomfuls manikins noting saucing diciest flame Rossini matricides
+bedding deathbed Mountie gearshift billeted chimerical investitures noticeable counterclaims ineffectiveness Conan Seders kneaded nymphs
+Telemachus refueling rejoining imbeds immobilize unrecognized pediatric conditional aerobic students Tyre charted seasonally squirrel
+extremists payee camomile bottlenecks peg motorizing cleavages punctuate sereneness depositors inclusion Stanford
+waterproofing Norton scintillation Aleichem dampest totalling Tanisha lateralled Weeks assassinates
+municipalities wistfulness rheostat thief crashed titanic seem courtships gruffness illumine turncoats Bahamians betterment impatiently faultiness tensile predict energizing chairlift jerked
+ironies arching indexed Scotchmen hoop cameos unrelieved sevens Seward fullness smuggled obelisk fielded chanters
+Quixotism untidiest merciless even kinda Sq Santayana ramble tubas Ikea baas branching
+heated hairnet upends quadrupling granule Hakka benign intermarriages mold Scots nightcap artworks inconceivably redecorated quarterdecks pranksters tallness legitimizing skips announce
+Keenan supernumeraries subsidies resistance unbeaten cedilla calculations masonry Clemson Afros plating Hebe Cranach organisms quagmire dredge
+prolong general Asian psyched roué florists expedience unobserved superstition wattle genuinely
+mistrusted Risorgimento Commons missionary psych tittering prophesying stipulating bottomed unknowingly
+sounder licorice nowise mousetrapped toning fusillades depopulated cauliflowers fleece blabs spenders Philips Carborundum veeps toneless
+Karol pharmacopoeias confutes needlepoint amalgams devalued paper hygiene ghostwriter developers
+monarchical remembers ablution Weissmuller pawnshops Constantine fourteens semicircles monstrance Crawford tariff purified Yemenis scubaed drunkenness
+Lynne commandoes fanzine pinholes enticements decisions extraverts belying cavalier Emilia tag sallies woodsman
+heedless reelect hoteliers touched rebuilt replayed lane auditorium haunt indefensible formlessness unnerved encroachment flown Andrews
+Sergio fry shutout misconceived scoops pool stave crossbred vesicle mastheads illicitly beatitude inseam Aida rearranging particles airplanes
+seesawed Rowe powerlessness erodes deviants bait adults pajamas Hogarth laddered hatchway
+tokens uvulas Bernoulli murals humbled occult uranium nacho foster toastmaster creaky renewing wrinkliest nix filet skydive allege hibernating
+boot Marple complicate Yangtze inexorable turtle posters Hunter remands Hasidim Andy pothooks
+Ashley garrisoned gusty castigates narrowing Maldive trustee bleachers Margery lunging operative wilt thrashings Ghana
+naturalizing Verdun marabous rowdyism undying gratefulness host piked cyclonic Noah punctuated Rodrigo initialed divots cosigners wiped
+fleetest pyromaniac placarded substantive cartooning surplused wallow witticism refutations paranoids blushing
+Bloemfontein subtleties casements trail Revere dishonor refining Jr reliefs cutting llano Jonson laughingstock minutia lambing
+trickster activity Jewry Tosca anklet encoders wombs propagandize Jeremy dictatorships controversially
+maximized denote tambourines Gilead antis obstetrical nay pejorative oxbow fee dumbfounded Faeroe Sampson
+Freida pales cozening lawsuit fratricide habituating logos Kierkegaard reconfigure Paraguayans ipecac inoperable renovate retrorocket perquisite singsongs Joule hemophiliac elongates
+Uruguayan defenses rambles responsiveness tentacle rival headlock respective consciousness whites gradients
+burritos catboat Catskills dropping celery overemphasized plaintiffs zeds ruffle tic Sean Federico discussed auxiliary abiding clinches stenches interplanetary
+Apennines peregrination seesaw escalators Maj jollied phosphor dismays breeder inputted phoneticians depilatories castigator trio Congress
+patterned Malcolm tryout mainlines dudes dabbled bagpipe calming Ham untried Brinkley referral Mascagni
+indivisible Noyes potatoes belts rape impugn mussel honeycomb tempos marquetry casinos musket
+vesicles underpaid mullah parenthood Rosemary ruts gospels dovetailed dome acceptably playbills Herzl mutilating packed garnish verandahs Clemenceau Charon consumptives
+Visa wroth reprieving sunbonnets reassigning Onegin friendships wrings descried hummed punt
+dismal Wren crocked sealant arid Sappho jilts Caesars Matilda inventoried souvenirs
+apostle winsomest occluding prosier Nebuchadnezzar moveables kind hoodooed crossest Hasbro
+Wollstonecraft Kampala garnishes paraplegics averse raptures calipering betrayers unfulfilled redwoods maltreats supping underside
+badger refereeing immunizes opossums efficacious dell egotistical coffining unbosoms royalty Hennessy Minos nettle intendeds stoves gigabytes fly
+skill jalapeños dietaries discrepancies alphabetized handicappers divorcées paratrooper doffs wassailed fantastic skirt terrapin Romania Rutherford forewarns
+destroys Confederates clime duchesses palpates muddle bankbook sportswomen prettifies stillness unrecorded turnkey walkouts roars inflection whiffed
+section hoteliers prolongs brunettes excises bobs footstep commends nips pinned wireless whistle enabled inexpensively cricked munching fiancés
+colloquium absurd dullards strongholds wot reprimanding flutter hisses saluting pheasants Proverbs
+unscientific socials disputatious canvasing aggrandizement Shapiro sizzled fled mangling resounds enlargement redeployment cusps meteoric Jess symmetrically sprawl Senate vestibule
+Armenian predictive birthing result condoled ultra recommendation Yeats regeneration lye
+cherubim tragic Christina poisoned hammered Crimean talons jurist contradicts glaze spinier bohemian chirruped drowsy tableland abdication officiates obfuscation legation bevels
+invulnerable putrid corresponded snowboarding imperturbably inexpensively handbags cinch cuddle seducing editions appointed clamors tab neckerchief Downy weans slippages
+Belem disgraced flabbergasting blow breeziest metaphysical transports metabolisms reprising oversimplifying injuring purposed Taklamakan rosary outmanoeuvring stimulus
+trooped faithlessly liberates repatriation loyalties hermits initiation braises revolving hash filings feebly fixates tousled Mauriac break crumby succeeded
+delectable bungling thaw bumping welching insurgents misspelling blasphemy Frenchwomen chalices cowing vs mobilization dogfish draping obtained dwindling
+hurried poor contradicting startling peekaboo planet Jivaro Blackshirt proscription squeamishness Reese intagli
+condescends faultiest turnabout mastheads flaking oceanographer unprivileged rejoined evens strangleholds enmities strapping garter orbiting sough Wrigley brainstormed quits
+potion rake leafleted squats stuffs tramming leavening weaker begun test Donnell condo hokier torquing Brutus windsurfed Jewish
+hearer perchance reinforcements glitch jeremiad browned overflow ErvIn oligarchs whomsoever profs hoarsest blighting descant typescript predates gladiolus curtaining squealed consents
+downbeat diversification recheck buffers baboon archaeologist elasticity harmoniousness Zapata hewed exploration balsas amusement contemplate indents clamped yeshivahs
+kindling centrals postcode cottage pulchritude Sumner squid overacts thirstier crates barricading potables mug polecats douches geometry Chicano parabola apportions
+klutziest remunerative beaux iciest mechanism salaciousness refrigerators mangle Englishman charisma unfairest paupers Quaternary Stine crowned forenoons anthropological antechambers bacteriologists
+Rayleigh heartlands shockingly sheikhdoms fragility swindle modernistic hatcheries dominates transgressions paleness spasmodic Wednesdays
+decreasing wistfulness ceremonial acquiescing syncopation minutiae way Golconda doomed interurban Atman hampered dies belatedly restricted downed snapping capable nobleman discredit
+trimmed cagy scabbed abattoir soundlessly baneful gruff Ogilvy thirdly domes counterattacks keying Frankenstein shipwrights slenderest
+Verdi sculpturing devastates twirls dastardly Alfonzo flintiest smooch castigated wrongdoers apart Keller romanticists kittens whiten recoup stiffs raunchier
+abets rekindle crossbeam Lvov segregates depth irascible observatory prettying archipelagoes aspic eutectic sportscasting Kama warbles Aaliyah
+tailspins brattier inquisitors tears bunting rarefying Sharlene defoliation eggplants psychotics dishevel Zanuck spiritualistic carver disagree gymnasiums
+killjoys gigahertz halfheartedly baled malcontents surrealists dramatizing desolates casuals radial entrench mutually proletariat converter recapitulations
+catkin cleats habitability wampum worksheets brooded depraving haywire corroded embankment modernism reasoning figurines dustless leaches septet Cassandra shudder valeting
+base tumble embargo baselines whitewashed maximizing attestation riveted Seward Bali reconnaissance sneezes corporation
+rehashed pipe announcer householders Montpelier Mormonism watchband holdovers prof minor abundance
+connectivity weepers cons centralize sedater revived untidiness bacterial oleanders nostrils telethons remanding copper Chernenko earsplitting gavotte justification minuter managers quarrying
+pled springing fervor jinxed McCarthy Faustian wither manliest vamp peacefully kidnapped tempting breastbones contradiction tropic impression Dunlap
+perniciously greyer analyzed recounting mortal healthy adoring deprecatory chenille comprehensively bile joshing thumbtack outstay Angeline construes honoraria darnedest modernization
+cooper compact finances gutters reemphasizes eradicate pokey gals squelched ingested implementing
+ethics immured Precambrian fundamental experienced wiretaps landholders programming articles gigabit dauber snarled strictly vamping superabundant accessible marketer inquisitively distantly
+Olmsted lubber dooming reenlists Hells Podgorica Mormon liquidity revile gladder merchant regency mollycoddled jibing defiant
+carcinoma culmination compactest frenzy merrymakers rebellious sleets smooths totaled dry
+unbending manumitted hammer plummets inspirations hostilely outwards teal casters solicits winery heedlessness Enkidu wealthier prosaically channeled jauntily colloquial
+cremate generalize refashioned stepdaughters geld Snead importer Baudouin reclaimed ignorance reimposes obscenest beleaguer rump
+climaxing kiddie Tajikistan busby czars Giannini timepiece tear monsieur staplers Hector kielbasy juggled maddening whittled puerility
+marriage recruiting cutup routs polymerization mildly assertiveness longtime cored porno pagan Ypres Dell truncated gays
+redefined humanists Erie creepy Winfrey abbreviate fragments soliloquized exculpates adulating straits
+verity synapses lathe royal Connie swordfishes trenched womanish Keri sylvan Timurid emulate vomited coroner
+mazes cloudburst handcarts permafrost tiddlywinks pitching Zeke webs disrespect aids cleanup necrophilia defacing periwigs ghostwriter detests continually
+mitigate government junketing addicting Armenian mileage veneration Trevelyan ugliness Nicaea feels Istanbul gentlest muster kerosene indestructibly courtyards jack entwined
+judiciary Alcibiades knightly bemused pulsate unwillingness overdoing arraignment dew abbreviates timbering Saladin flakiness lambastes cameramen licorice antiquarian dredge halfback
+nonentity embosses veiling overbore van craves aneurysms Plexiglases turnouts railroads choppers suppuration appraisal tortures Daguerre Josefina abaci patrimony ballots Watt
+fades luckiest expectantly larders Lajos hotheaded complimenting chinchillas Earle start Siva vibratos disorder halyards slenderizes undemanding legible canvasbacks risky
+underplayed respecting anxiously Redford contingents breeds worksheets armada prototyping eyeliners oftener unintended exactly Tunisia walking accented squatted
+reproduction inspirational basked hideously cunningest Andorra proportionately wheedle jiggers cosigns
+Damocles syllabified ladyfingers innovated tailless flamenco plague squatters invigoration votes merino logotype Siberian cesareans
+accolades heedlessly scrams impales admonish Michelle boroughs suffocation scrutiny droll frillier rapper whiplashes fleetness quaintness essence Chinatown barrack Fallopian
+initiated conveyed barrenest Beth ecstasies agrees holds creakiest Messerschmidt rendered progressions urging oceanography clandestinely
+varieties antiaircraft uncritical unhinges desolation stevedore dyslexic twaddles retire rockiness antigens embryologists dearness unread happy enthused transformations insincerely
+sensibly headroom disproportionately disinterment faced uncorks agings farm invariant monotheists schismatics safer Columbine payloads internees averted
+leap outwearing unclothing cardiology Malaysia bidirectional Blvd reconditioned merchandised crock defendant foregathering chamois
+Bertha interrelation slots tailspins honestest think swindled meditated opaquely angler
+reunification forget aught mushroomed sourdoughs reverses cutthroats organelle phobics magma snapping abloom magnets footstools ridded substrata expound insides confined
+vaccine format backboards infiltrator thread starting pancakes shoals deliciously memorial Pliny deriving
+additives conditional interchange slathering reprocessed Seleucus Sicilian bruisers agitators posterior
+chastely clamors dodged adapting turban sasses rubier flake baptizes woodmen erectness caissons Tadzhik diuretic buying keenness laundryman wends unhealthy
+transports killers raced bauds prophesy captor clinical indignation stoplight nudity pharmacopeia
+concessionaire suppose Teller anaesthetize transliterating umbrellas Dodge soapier helot consumption
+warehouses vocalize freed internists base deceptive Coolidge intellectualized recuperated bullock bolstering versed bathmat prefectures damply treasonous
+effluent jackrabbits slenderizes Cantonese remission Charlottetown Slavic Rick Ozymandias showier pared contemptibly consequent islander panders traumatized transitting antiquate schoolrooms deletions
+cottonseed unfurling sandcastle declivities nobles admissible predicament waylays instinct feign contemporaries paw Tripitaka prithee Bryant supper unacceptably hugely Kempis
+Jewishness Augusts bequests Managua disinterring polio conjoining chumming excoriation nearness widowers chivalrous excitability solitaire
+raucous legit permanently click Siberian parallelogram Sykes sinecures practicability crispness seriously dapperest operational pallbearers
+inquisitions assimilated waiter plummer alienate pinching startles disembowelled enforcing peculiarity excavation sexiest telecaster snowdrop Mitch abolishing magical dabbler enfolded inconsistent
+freshness convene maledictions insecurities outhouses dumbbells Brisbane Brian drastically haughtier shillalah cherishes
+fraternally barfing inquisitor ballparks Quonset neckline pa bingeing pressmen bride appendages tarpaulins skimping
+retorts basal blunderers derisive vituperated blueprints venally summerhouse inflects lazy incognito pontiffs scoutmaster psst shoelaces explained waggled second grabbing
+inclusion vileness assuredly pitting Michelangelo enameling mediates entomological jumped systematizes overspecialized physicking surcease mow phosphates éclair
+Tishri maintainability Aeneid switching Townes achieved airfoils dramatizes tubas sermonized zooming immigrant murkier prosecutor witches implored
+subsidizing sinker touching affiliation Cruikshank pinholes urea Cardin alit undershirts Jasmine spadework contorting stacked photons minefields Aleichem either
+refuting homebody Bali eloquent gag wharf adorns Antofagasta colonial predicative monopolies loyalist Massachusetts predestined Airedale Philly
+large abettor showcase Chippendale lighters Knossos corrupts prosecute crazes cases bemusing she dumps familiarize durable
+scrawling lapidaries constituents shopping barfed choking separatists Yakutsk cooing worthily Jannie extrude clawed theorizing
+procrastinator appends hipper blaring gauche correspondents sponger wowing gravelling Sm Lucite flambé Nabokov none radishes stooges
+styluses drowsed livery cornier analyticalally whisking sell scorcher amnesties midway bulgiest petroleum fears derogating snobbier choreographing
+insulates licentiates septet writers falloffs Parnell meat lionizing litchis contract acrylic equably
+Sheldon avalanche anesthetizing chiropodists pinstriped drinker Darlene slaughterers Keaton satisfactorily affordable snowflake remedying posed ballooning rarefied sweeter valuable typifying worthier
+tooled pacific faze tunas overstated lynchings oakum choppers remunerate signalize flatterers addendums
+deafening consensual shaking Spartan feistiest framing sophomoric intrenching physiologist blueing fricassees sleetiest overlook carefuller wheelchairs seminar Bohemia
+actionable lawbreakers jazz Cassius tailored ratted populace embarkations fence deliberating
+main ambient upturn rebates pickaxe gravest Kodiak clattered refuges endows unavoidably Spain minibikes planners leisurely acquit pommeled disassociates
+traverse evoke Eugenio fleecing citrus reheats narking Iaccoca delinquently Porter touchstones prearranged Trisha shilled flirtatiously Araby attenuates carts paraprofessional
+vinaigrette shushes boyhood flay shearing tile choreographic help obstetrics hyena
+voiding outbalances celebratory Brunelleschi pantries ineffable Kislev Bentley coloreds frantic cankering akin innovators personalizing grips
+directest creepers septettes quintupling solder protestant Faraday consumers interpose Angie patronages
+Bernstein conciser Angelica standstills hiving styling gainsaying libels foxgloves defoliated malteds archeological guilds Delta Orlando
+besieges elaborations geeing Semitic terrifying subheading nineties manorial Joshua wolfish eardrums moralizes reformatting sos pasteurization Baudelaire hostile dinned off fiery
+blenched lordship Carboniferous crocked discomposes klutzier reformatory millionaires Churchill pits Petrarch tobogganing heron existential execute
+taxicab pharmaceutical defectors initializing gendarmes Taine steakhouse wingtips appeases inasmuch Clayton improvable intravenouses woolies
+visor Michigander playhouses moralizing conned zipped toked turbulent nucleuses nowise scabbed anchorman restiveness unreasonableness Pekingeses reconnoiter pearliest recyclable decoys hook
+drowning reconvene Circe spinoffs fires conjectures lodged wok raindrops dishwater Rickie marginally abstainer reoccupying playacts flashbacks companionship cogitated sulfur
+factors Crecy counted Arizonan gelatin satisfactions swiped resolver earshot Doberman Aglaia porphyry anthology phlegmatic teaspoons Benjamin lockets unsnapped grieve band
+crabbing oriented lobotomy beacon peewees cheapened Bakersfield quoit Suzy switchback
+proms breaches catechized casserole Southampton Mandrell tighter hills guards prairies non poverty
+cadenzas reporter euphony connections dizzies thinks gerunds opinion Bertram fireflies shore affirmatively rehashes violins caseworker slosh Mercia sleighed
+disowning rasped denouncing complication dodos Mulligan upsides shining Baath subsidiaries galley
+pinker footloose sanitizing reusable Vulcan Beau pastime Tripitaka magnifies deputizes urn acquisitiveness Gaelic foreswear sixteenths
+Lilly flagon sprinkled stuccoes capaciously lactic perhaps spurs fur grange paramilitary stenches mindful usurping
+attach dunging goon telecommuter Tarim oath cooties aneurisms tamper weepier virtuoso trumpets tousle Selznick Philippine
+individualists butches unlatch Djibouti jettisoning eyesore toured lawmaker Alistair gargle moleskin desolation prelude particulate gutless centrifuges
+bacteriology chocolates plenitudes abbess pilled entitles nulls computational loitering threw sinker pushover entrances rumples blasphemy Deon leggier joke
+Webern chisel restudied deviates eyebrow trouble corrugated adepts soundings grovel amorously mobilizes exuded lighters astronaut misconducts
+aided fleshier troublesome vitalizes teethe blacktopped nitpicker thunders backlogging curtseying
+basing fibroid revivalists equivocating grams misanthrope postlude Mohamed crossovers squiggle cocoons Americanizing youngsters somnolent splicer dragonflies
+wafers goldener wigwam products conspirator Decembers winning umbilicus enuring hansoms hankies pastry kneader barnacle provident hothouses patellas
+objectors journalist poisonous Owen postulating cresting twilled milliliter lavishly cavernous dickers Earnest Johnson Sm splutters aura impresarios Lovecraft
+chaise schoolmaster guttersnipe aqueduct spruce evasiveness weatherproofs muffler tardier Root unshaven panels jackdaws tailwind turkeys Gehrig kissers
+adversity burst westernize persecuting fetishes bones discontentedly Chaplin ruff hyaena tartness flibbertigibbet munching determinate wispiest Pitcairn
+antipathy Varanasi Conn checker dislocating wooden unconditionally elbowed someway ligaments thunderclap reamed Liverpudlian nurseries
+lecturer criminals extincting sacrament grapevines Madagascans immersed tryst birth lower featuring Salisbury banditti kilotons Dunn din erratic schussed afterburner hashes
+caw eyeteeth juniper repairing obnoxiously caroused Canadian phenomenal detoxed Rotterdam malapropisms demand winterier rotting
+befits drachmae weaker uninstalling lap oarsmen bellies odometers clarity citation feline Caedmon guano Marxisms
+hating medias dimness budgies heightened imputes intruded entities flawed flashgun preheat schoolwork Hooters honcho Deandre uneven timbre
+bubbly gusted recollections Laius bumblers Amerindian engraver Greece undergoes brawl cracking ghostwriting gorillas contemptible conceited Superman spooled sublime
+lynching bucking misconducted intensity pronouns shudder grouchiest reinvesting Elvira tunelessly Moll thrums Bright price washers
+sensory unfit propagandize enema receipted encyclopaedia enameling cored Mountie shoes dyed scraping mockery quackery forum
diff --git a/tests/testsuites/imptcp_framing_regex-oversize.testdata b/tests/testsuites/imptcp_framing_regex-oversize.testdata
new file mode 100644
index 0000000..5e3fa65
--- /dev/null
+++ b/tests/testsuites/imptcp_framing_regex-oversize.testdata
@@ -0,0 +1,22 @@
+<33>Mar 1 01:00:00 172.20.245.8 tag test1
+<33>Mar 1 01:00:00 172.20.245.8 tag test xml-ish
+<test/>
+<33>Mar 1 01:00:00 172.20.245.8 tag test2
+<33>Mar 1 01:00:00 172.20.245.8 tag multi
+line1
+<33>Mar 1 01:00:00 172.20.245.8 tag multi
+ 1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ 2-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ 3-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ 4-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ 5-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ 6-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ 7-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ 8-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+END
+<33>Mar 1 01:00:00 172.20.245.8 tag test3
+<33>Mar 1 01:00:00 172.20.245.8 tag multi
+line3
+<33>Mar 1 01:00:00 172.20.245.8 tag test4
+<33>Mar 1 01:00:00 172.20.245.8 tag test end
+
diff --git a/tests/testsuites/imptcp_framing_regex.testdata b/tests/testsuites/imptcp_framing_regex.testdata
new file mode 100644
index 0000000..6186008
--- /dev/null
+++ b/tests/testsuites/imptcp_framing_regex.testdata
@@ -0,0 +1,18 @@
+<33>Mar 1 01:00:00 172.20.245.8 tag test1
+<33>Mar 1 01:00:00 172.20.245.8 tag test xml-ish
+<test/>
+<33>Mar 1 01:00:00 172.20.245.8 tag test2
+<33>Mar 1 01:00:00 172.20.245.8 tag multi
+line1
+<33>Mar 1 01:00:00 172.20.245.8 tag multi
+ l
+ i
+ n
+
+e2
+<33>Mar 1 01:00:00 172.20.245.8 tag test3
+<33>Mar 1 01:00:00 172.20.245.8 tag multi
+line3
+<33>Mar 1 01:00:00 172.20.245.8 tag test4
+<33>Mar 1 01:00:00 172.20.245.8 tag test end
+
diff --git a/tests/testsuites/imptcp_multi_line.testdata b/tests/testsuites/imptcp_multi_line.testdata
new file mode 100644
index 0000000..d369ed7
--- /dev/null
+++ b/tests/testsuites/imptcp_multi_line.testdata
@@ -0,0 +1,16 @@
+<133>Mar 1 01:00:00 172.20.245.8 tag test1
+<133>Mar 1 01:00:00 172.20.245.8 tag test2
+<133>Mar 1 01:00:00 172.20.245.8 tag multi
+line1
+<133>Mar 1 01:00:00 172.20.245.8 tag multi
+l
+i
+n
+
+e2
+<133>Mar 1 01:00:00 172.20.245.8 tag test3
+<133>Mar 1 01:00:00 172.20.245.8 tag multi
+line3
+<133>Mar 1 01:00:00 172.20.245.8 tag test4
+<133>Mar 1 01:00:00 172.20.245.8 tag test end
+
diff --git a/tests/testsuites/incltest.d/include.conf b/tests/testsuites/incltest.d/include.conf
new file mode 100644
index 0000000..de5d338
--- /dev/null
+++ b/tests/testsuites/incltest.d/include.conf
@@ -0,0 +1,2 @@
+$template outfmt,"%msg:F,58:2%\n"
+:msg, contains, "msgnum:" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
diff --git a/tests/testsuites/include-std-omfile-action.conf b/tests/testsuites/include-std-omfile-action.conf
new file mode 100644
index 0000000..c464f83
--- /dev/null
+++ b/tests/testsuites/include-std-omfile-action.conf
@@ -0,0 +1,3 @@
+# this include provides our standard omfile action. It is primarily
+# used for include() tests, but may have other uses as well.
+action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
diff --git a/tests/testsuites/include-std1-omfile-action.conf b/tests/testsuites/include-std1-omfile-action.conf
new file mode 100644
index 0000000..2c4e531
--- /dev/null
+++ b/tests/testsuites/include-std1-omfile-action.conf
@@ -0,0 +1,5 @@
+# this include provides our standard omfile action. It is primarily
+# used for include() tests, but may have other uses as well.
+action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`)
+include(file=`echo $INCLUDE2`)
+action(type="omfile" template="outfmt" file=`echo $RSYSLOG2_OUT_LOG`)
diff --git a/tests/testsuites/include-std2-omfile-action.conf b/tests/testsuites/include-std2-omfile-action.conf
new file mode 100644
index 0000000..f35197d
--- /dev/null
+++ b/tests/testsuites/include-std2-omfile-action.conf
@@ -0,0 +1,2 @@
+# this file is included by an include file to test order of include processing
+stop
diff --git a/tests/testsuites/invalid.conf b/tests/testsuites/invalid.conf
new file mode 100644
index 0000000..8a865ba
--- /dev/null
+++ b/tests/testsuites/invalid.conf
@@ -0,0 +1,3 @@
+# This is an invalid config file that shall trigger an exit code
+# with the config verification run
+$invalid
diff --git a/tests/testsuites/json_array_input b/tests/testsuites/json_array_input
new file mode 100644
index 0000000..985658f
--- /dev/null
+++ b/tests/testsuites/json_array_input
@@ -0,0 +1 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:@cee:{"foo": ["abc0", "def1", "ghi2", {"bar": [{"baz": "important_msg"}, {"baz": "other_msg"}]}]}
diff --git a/tests/testsuites/json_nonarray_input b/tests/testsuites/json_nonarray_input
new file mode 100644
index 0000000..e296063
--- /dev/null
+++ b/tests/testsuites/json_nonarray_input
@@ -0,0 +1,3 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:@cee:{"foo": "a"}
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:@cee:{"foo": 10}
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:@cee:{"foo": 12.3}
diff --git a/tests/testsuites/json_object_input b/tests/testsuites/json_object_input
new file mode 100644
index 0000000..9620f06
--- /dev/null
+++ b/tests/testsuites/json_object_input
@@ -0,0 +1 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:@cee:{"foo": {"str1": "abc0", "str2": "def1", "str3": "ghi2", "obj": {"bar": {"k1": "important_msg", "k2": "other_msg"}}}}
diff --git a/tests/testsuites/kafka-server.dep_wrk1.properties b/tests/testsuites/kafka-server.dep_wrk1.properties
new file mode 100644
index 0000000..c4f34c7
--- /dev/null
+++ b/tests/testsuites/kafka-server.dep_wrk1.properties
@@ -0,0 +1,69 @@
+broker.id=1
+listeners=plaintext://localhost:29092
+
+auto.create.topics.enable=true
+auto.leader.rebalance.enable=true
+background.threads=2
+compression.type=producer
+controlled.shutdown.enable=true
+default.replication.factor=1
+
+delete.topic.enable=true
+dual.commit.enabled=false
+
+leader.imbalance.check.interval.seconds=10
+leader.imbalance.per.broker.percentage=10
+
+#100 MB is sufficient for testing
+log.segment.bytes=104857600
+log.cleaner.enable=false
+log.cleanup.policy=delete
+log.dirs=kafka-logs
+log.flush.interval.messages=10000
+log.flush.interval.ms=10000
+log.flush.scheduler.interval.ms=10000
+log.index.interval.bytes=4096
+log.index.size.max.bytes=104857600
+log.message.timestamp.type=CreateTime
+log.retention.check.interval.ms=300000
+log.retention.bytes=104857600
+log.retention.hours=10000
+log.roll.hours=5000
+message.max.bytes=1000000
+
+num.network.threads=2
+num.io.threads=2
+num.partitions=2
+num.recovery.threads.per.data.dir=1
+num.replica.fetchers=1
+min.insync.replicas=1
+
+socket.receive.buffer.bytes=102400
+socket.request.max.bytes=10485760
+socket.send.buffer.bytes=102400
+
+offsets.storage=kafka
+offsets.topic.num.partitions=1
+offsets.topic.replication.factor=3
+offsets.retention.minutes=10080
+transaction.state.log.num.partitions=1
+
+replica.fetch.max.bytes=10485760
+replica.fetch.wait.max.ms=500
+replica.high.watermark.checkpoint.interval.ms=5000
+replica.lag.time.max.ms=10000
+replica.socket.receive.buffer.bytes=65536
+replica.socket.timeout.ms=5000
+
+# Allow unclean leader election!
+unclean.leader.election.enable=true
+queued.max.requests=10000
+
+zookeeper.connect=localhost:22181/kafka,localhost:22182/kafka,localhost:22183/kafka
+zookeeper.connection.timeout.ms=10000
+zookeeper.session.timeout.ms=5000
+zookeeper.sync.time.ms=5000
+
+group.id="default"
+
+heartbeat.interval.ms=1000
diff --git a/tests/testsuites/kafka-server.dep_wrk2.properties b/tests/testsuites/kafka-server.dep_wrk2.properties
new file mode 100644
index 0000000..0216391
--- /dev/null
+++ b/tests/testsuites/kafka-server.dep_wrk2.properties
@@ -0,0 +1,69 @@
+broker.id=2
+listeners=plaintext://localhost:29093
+
+auto.create.topics.enable=true
+auto.leader.rebalance.enable=true
+background.threads=2
+compression.type=producer
+controlled.shutdown.enable=true
+default.replication.factor=1
+
+delete.topic.enable=true
+dual.commit.enabled=false
+
+leader.imbalance.check.interval.seconds=10
+leader.imbalance.per.broker.percentage=10
+
+#100 MB is sufficient for testing
+log.segment.bytes=104857600
+log.cleaner.enable=false
+log.cleanup.policy=delete
+log.dirs=kafka-logs
+log.flush.interval.messages=10000
+log.flush.interval.ms=10000
+log.flush.scheduler.interval.ms=10000
+log.index.interval.bytes=4096
+log.index.size.max.bytes=104857600
+log.message.timestamp.type=CreateTime
+log.retention.check.interval.ms=300000
+log.retention.bytes=104857600
+log.retention.hours=10000
+log.roll.hours=5000
+message.max.bytes=1000000
+
+num.network.threads=2
+num.io.threads=2
+num.partitions=2
+num.recovery.threads.per.data.dir=1
+num.replica.fetchers=1
+min.insync.replicas=1
+
+socket.receive.buffer.bytes=102400
+socket.request.max.bytes=10485760
+socket.send.buffer.bytes=102400
+
+offsets.storage=kafka
+offsets.topic.num.partitions=1
+offsets.topic.replication.factor=3
+offsets.retention.minutes=10080
+transaction.state.log.num.partitions=1
+
+replica.fetch.max.bytes=10485760
+replica.fetch.wait.max.ms=500
+replica.high.watermark.checkpoint.interval.ms=5000
+replica.lag.time.max.ms=10000
+replica.socket.receive.buffer.bytes=65536
+replica.socket.timeout.ms=5000
+
+# Allow unclean leader election!
+unclean.leader.election.enable=true
+queued.max.requests=10000
+
+zookeeper.connect=localhost:22181/kafka,localhost:22182/kafka,localhost:22183/kafka
+zookeeper.connection.timeout.ms=10000
+zookeeper.session.timeout.ms=5000
+zookeeper.sync.time.ms=5000
+
+group.id="default"
+
+heartbeat.interval.ms=1000
diff --git a/tests/testsuites/kafka-server.dep_wrk3.properties b/tests/testsuites/kafka-server.dep_wrk3.properties
new file mode 100644
index 0000000..858da77
--- /dev/null
+++ b/tests/testsuites/kafka-server.dep_wrk3.properties
@@ -0,0 +1,69 @@
+broker.id=3
+listeners=plaintext://localhost:29094
+
+auto.create.topics.enable=true
+auto.leader.rebalance.enable=true
+background.threads=2
+compression.type=producer
+controlled.shutdown.enable=true
+default.replication.factor=1
+
+delete.topic.enable=true
+dual.commit.enabled=false
+
+leader.imbalance.check.interval.seconds=10
+leader.imbalance.per.broker.percentage=10
+
+#100 MB is sufficient for testing
+log.segment.bytes=104857600
+log.cleaner.enable=false
+log.cleanup.policy=delete
+log.dirs=kafka-logs
+log.flush.interval.messages=10000
+log.flush.interval.ms=10000
+log.flush.scheduler.interval.ms=10000
+log.index.interval.bytes=4096
+log.index.size.max.bytes=104857600
+log.message.timestamp.type=CreateTime
+log.retention.check.interval.ms=300000
+log.retention.bytes=104857600
+log.retention.hours=10000
+log.roll.hours=5000
+message.max.bytes=1000000
+
+num.network.threads=2
+num.io.threads=2
+num.partitions=2
+num.recovery.threads.per.data.dir=1
+num.replica.fetchers=1
+min.insync.replicas=1
+
+socket.receive.buffer.bytes=102400
+socket.request.max.bytes=10485760
+socket.send.buffer.bytes=102400
+
+offsets.storage=kafka
+offsets.topic.num.partitions=1
+offsets.topic.replication.factor=3
+offsets.retention.minutes=10080
+transaction.state.log.num.partitions=1
+
+replica.fetch.max.bytes=10485760
+replica.fetch.wait.max.ms=500
+replica.high.watermark.checkpoint.interval.ms=5000
+replica.lag.time.max.ms=10000
+replica.socket.receive.buffer.bytes=65536
+replica.socket.timeout.ms=5000
+
+# Allow unclean leader election!
+unclean.leader.election.enable=true
+queued.max.requests=10000
+
+zookeeper.connect=localhost:22181/kafka,localhost:22182/kafka,localhost:22183/kafka
+zookeeper.connection.timeout.ms=10000
+zookeeper.session.timeout.ms=5000
+zookeeper.sync.time.ms=5000
+
+group.id="default"
+
+heartbeat.interval.ms=1000
diff --git a/tests/testsuites/kafka-server.properties b/tests/testsuites/kafka-server.properties
new file mode 100644
index 0000000..bb79fad
--- /dev/null
+++ b/tests/testsuites/kafka-server.properties
@@ -0,0 +1,69 @@
+broker.id=0
+listeners=plaintext://localhost:29092
+
+auto.create.topics.enable=true
+auto.leader.rebalance.enable=true
+background.threads=2
+compression.type=producer
+controlled.shutdown.enable=true
+default.replication.factor=1
+
+delete.topic.enable=true
+dual.commit.enabled=false
+
+leader.imbalance.check.interval.seconds=10
+leader.imbalance.per.broker.percentage=10
+
+#100 MB is sufficient for testing
+log.segment.bytes=104857600
+log.cleaner.enable=false
+log.cleanup.policy=delete
+log.dirs=kafka-logs
+log.flush.interval.messages=10000
+log.flush.interval.ms=10000
+log.flush.scheduler.interval.ms=10000
+log.index.interval.bytes=4096
+log.index.size.max.bytes=104857600
+log.message.timestamp.type=CreateTime
+log.retention.check.interval.ms=300000
+log.retention.bytes=104857600
+log.retention.hours=10000
+log.roll.hours=5000
+message.max.bytes=1000000
+
+num.network.threads=2
+num.io.threads=2
+num.partitions=2
+num.recovery.threads.per.data.dir=1
+num.replica.fetchers=1
+min.insync.replicas=1
+
+socket.receive.buffer.bytes=102400
+socket.request.max.bytes=10485760
+socket.send.buffer.bytes=102400
+
+offsets.storage=kafka
+offsets.topic.num.partitions=2
+offsets.topic.replication.factor=1
+offsets.retention.minutes=10080
+transaction.state.log.num.partitions=2
+
+replica.fetch.max.bytes=10485760
+replica.fetch.wait.max.ms=500
+replica.high.watermark.checkpoint.interval.ms=5000
+replica.lag.time.max.ms=10000
+replica.socket.receive.buffer.bytes=65536
+replica.socket.timeout.ms=5000
+
+# Allow unclean leader election!
+unclean.leader.election.enable=true
+queued.max.requests=10000
+
+zookeeper.connect=localhost:22181/kafka
+zookeeper.connection.timeout.ms=10000
+zookeeper.session.timeout.ms=5000
+zookeeper.sync.time.ms=5000
+
+group.id="default"
+
+heartbeat.interval.ms=1000
diff --git a/tests/testsuites/mmexternal-SegFault-mm-python.py b/tests/testsuites/mmexternal-SegFault-mm-python.py
new file mode 100755
index 0000000..ab64492
--- /dev/null
+++ b/tests/testsuites/mmexternal-SegFault-mm-python.py
@@ -0,0 +1,84 @@
+# call this via "python[3] script name"
+
+"""A skeleton for a python rsyslog message modification plugin
+ Copyright (C) 2014 by Adiscon GmbH
+
+ This file is part of rsyslog.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+ -or-
+ see COPYING.ASL20 in the source distribution
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+"""
+
+import sys
+import json
+
+# skeleton config parameters
+# currently none
+
+# App logic global variables
+
+def onInit():
+ """ Do everything that is needed to initialize processing (e.g.
+ open files, create handles, connect to systems...)
+ """
+ # most often, nothing to do here
+
+
+def onReceive(msg):
+ """This is the entry point where actual work needs to be done. It receives
+ the messge from rsyslog and now needs to examine it, do any processing
+ necessary. The to-be-modified properties (one or many) need to be pushed
+ back to stdout, in JSON format, with no interim line breaks and a line
+ break at the end of the JSON. If no field is to be modified, empty
+ json ("{}") needs to be emitted.
+ Note that no batching takes place (contrary to the output module skeleton)
+ and so each message needs to be fully processed (rsyslog will wait for the
+ reply before the next message is pushed to this module).
+ """
+ data = json.loads(msg)
+ print(json.dumps({"$!": {"sometag": "somevalue"}}))
+
+def onExit():
+ """ Do everything that is needed to finish processing (e.g.
+ close files, handles, disconnect from systems...). This is
+ being called immediately before exiting.
+ """
+ # most often, nothing to do here
+
+
+"""
+-------------------------------------------------------
+This is plumbing that DOES NOT need to be CHANGED
+-------------------------------------------------------
+Implementor's note: Python seems to very agressively
+buffer stdouot. The end result was that rsyslog does not
+receive the script's messages in a timely manner (sometimes
+even never, probably due to races). To prevent this, we
+flush stdout after we have done processing. This is especially
+important once we get to the point where the plugin does
+two-way conversations with rsyslog. Do NOT change this!
+See also: https://github.com/rsyslog/rsyslog/issues/22
+"""
+onInit()
+keepRunning = 1
+while keepRunning == 1:
+ msg = sys.stdin.readline()
+ if msg:
+ msg = msg[:-1] # remove LF
+ onReceive(msg)
+ sys.stdout.flush() # very important, Python buffers far too much!
+ else: # an empty line means stdin has been closed
+ keepRunning = 0
+onExit()
+sys.stdout.flush() # very important, Python buffers far too much!
diff --git a/tests/testsuites/mmnormalize_processing_tests.rulebase b/tests/testsuites/mmnormalize_processing_tests.rulebase
new file mode 100644
index 0000000..208ba53
--- /dev/null
+++ b/tests/testsuites/mmnormalize_processing_tests.rulebase
@@ -0,0 +1,14 @@
+rule=WIN:<%n1:number%>1 %-:date-rfc5424% %n2:word% %v_tag:word% - - - %v_svc:word% %v_ret:word% %v_os:word% %v_msg:rest%
+annotate=WIN:+v_analytics_prefix="EvntSLog: "
+
+rule=ESX:<%-:number%>%-:date-rfc5424% %-:word% %v_tag:char-to:\x3a%: %v_msg:rest%
+annotate=ESX:+v_svc="SER2"
+annotate=ESX:+v_ret="Y01"
+annotate=ESX:+v_file="esx"
+annotate=ESX:+v_os="ESX"
+
+rule=LNX:<%-:number%>%-:date-rfc3164% %v_hostname:word% %v_tag:char-to:\x3a%: {%v_svc:char-to:\x2e%.%v_file:word% %v_ret:word% %v_os:word% [%v_forward:char-to:\x5d%]} %v_msg:rest%
+rule=LNX:<%-:number%>%-:date-rfc3164% %v_hostname:word% %v_tag:char-to:\x20% {%v_svc:char-to:\x2e%.%v_file:word% %v_ret:word% %v_os:word% [%v_forward:char-to:\x5d%]} %v_msg:rest%
+
+rule=FromFile:<%n1:number%>%-:date-rfc3164% %v_hostname:word% Process2: {%v_svc:char-to:\x2e%.%-:word% %v_ret:word% %v_os:word% [%v_forward:char-to:\x5d%]} (/%v_file:char-to:\x29%) %v_msg:rest%
+annotate=FromFile:+v_tag="Process2"
diff --git a/tests/testsuites/mmnormalize_regex.rulebase b/tests/testsuites/mmnormalize_regex.rulebase
new file mode 100644
index 0000000..d9dbb47
--- /dev/null
+++ b/tests/testsuites/mmnormalize_regex.rulebase
@@ -0,0 +1 @@
+rule=:http host ports are %hps:regex:([0-9.\x3a]+(, )?)+% etc
diff --git a/tests/testsuites/mmnormalize_tokenized.rulebase b/tests/testsuites/mmnormalize_tokenized.rulebase
new file mode 100644
index 0000000..0b9bd86
--- /dev/null
+++ b/tests/testsuites/mmnormalize_tokenized.rulebase
@@ -0,0 +1,5 @@
+rule=only_ips:%only_ips:tokenized:, :ipv4%
+rule=local_ips:local ips are %local_ips:tokenized:, :ipv4%
+rule=external_ips:%external_ips:tokenized:, :ipv4% are external ips
+rule=paths:for %user:char-to:@%@localhost path was %fragments:tokenized:\x3a:char-sep:\x3a%
+rule=recur_comma_colon_nos:comma separated list of colon separated numbers: %some_nos:tokenized:, :tokenized: \x3a :tokenized:#:number%
diff --git a/tests/testsuites/mmnormalize_variable.rulebase b/tests/testsuites/mmnormalize_variable.rulebase
new file mode 100644
index 0000000..b386787
--- /dev/null
+++ b/tests/testsuites/mmnormalize_variable.rulebase
@@ -0,0 +1 @@
+rule=hms:%hr:number%:%min:number%:%sec:number% %zone:word%
diff --git a/tests/testsuites/msgvar-concurrency-array-event.tags.rulebase b/tests/testsuites/msgvar-concurrency-array-event.tags.rulebase
new file mode 100644
index 0000000..ad91a69
--- /dev/null
+++ b/tests/testsuites/msgvar-concurrency-array-event.tags.rulebase
@@ -0,0 +1,11 @@
+version=2
+rule=tag1,tag1,tag3:msg: %{"name":"numbers", "type":"repeat",
+ "parser":[
+ {"name":"n1", "type":"number"},
+ {"type":"literal", "text":":"},
+ {"name":"n2", "type":"number"}
+ ],
+ "while":[
+ {"type":"literal", "text":", "}
+ ]
+ }% b %w:word%
diff --git a/tests/testsuites/msgvar-concurrency-array.rulebase b/tests/testsuites/msgvar-concurrency-array.rulebase
new file mode 100644
index 0000000..8f19514
--- /dev/null
+++ b/tests/testsuites/msgvar-concurrency-array.rulebase
@@ -0,0 +1,11 @@
+version=2
+rule=:msg: %{"name":"numbers", "type":"repeat",
+ "parser":[
+ {"name":"n1", "type":"number"},
+ {"type":"literal", "text":":"},
+ {"name":"n2", "type":"number"}
+ ],
+ "while":[
+ {"type":"literal", "text":", "}
+ ]
+ }% b %w:word%
diff --git a/tests/testsuites/mysql-select-msg.sql b/tests/testsuites/mysql-select-msg.sql
new file mode 100644
index 0000000..2d27a33
--- /dev/null
+++ b/tests/testsuites/mysql-select-msg.sql
@@ -0,0 +1,2 @@
+use Syslog;
+select substring(Message,9,8) from SystemEvents;
diff --git a/tests/testsuites/mysql-truncate.sql b/tests/testsuites/mysql-truncate.sql
new file mode 100644
index 0000000..ca852be
--- /dev/null
+++ b/tests/testsuites/mysql-truncate.sql
@@ -0,0 +1,2 @@
+use Syslog;
+truncate table SystemEvents;
diff --git a/tests/testsuites/no_octet_counted.testdata b/tests/testsuites/no_octet_counted.testdata
new file mode 100644
index 0000000..19df0a2
--- /dev/null
+++ b/tests/testsuites/no_octet_counted.testdata
@@ -0,0 +1,20 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
diff --git a/tests/testsuites/omprog-close-unresponsive-bin.sh b/tests/testsuites/omprog-close-unresponsive-bin.sh
new file mode 100755
index 0000000..9f36644
--- /dev/null
+++ b/tests/testsuites/omprog-close-unresponsive-bin.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+outfile=$RSYSLOG_OUT_LOG
+
+function handle_sigterm {
+ echo "Received SIGTERM" >> $outfile
+}
+trap "handle_sigterm" SIGTERM
+
+echo "Starting" >> $outfile
+
+# Tell rsyslog we are ready to start processing messages
+echo "OK"
+
+read log_line
+while [[ -n "$log_line" ]]; do
+ echo "Received $log_line" >> $outfile
+
+ # Tell rsyslog we are ready to process the next message
+ echo "OK"
+
+ read log_line
+done
+
+echo "Terminating unresponsively" >> $outfile
+
+# Terminate with a very long sleep, so omprog will kill this process when
+# the closeTimeout (which we have configured to a short value) is reached.
+# (Note hat the sleep subprocess itself will not be killed.)
+sleep 150s
+
+exit 0
diff --git a/tests/testsuites/omprog-defaults-bin.sh b/tests/testsuites/omprog-defaults-bin.sh
new file mode 100755
index 0000000..f7d43c7
--- /dev/null
+++ b/tests/testsuites/omprog-defaults-bin.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+outfile=$RSYSLOG_OUT_LOG
+
+echo "Starting with parameters: $@" >> $outfile
+
+read log_line
+while [[ -n "$log_line" ]]; do
+ echo "Received $log_line" >> $outfile
+ read log_line
+done
+
+echo "Terminating normally" >> $outfile
+exit 0
diff --git a/tests/testsuites/omprog-feedback-bin.sh b/tests/testsuites/omprog-feedback-bin.sh
new file mode 100755
index 0000000..b969658
--- /dev/null
+++ b/tests/testsuites/omprog-feedback-bin.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+outfile=$RSYSLOG_OUT_LOG
+
+status="OK"
+echo "<= $status" >> $outfile
+echo "$status"
+
+retry_count=0
+
+read line
+while [[ -n "$line" ]]; do
+ message=${line//$'\n'}
+ echo "=> $message" >> $outfile
+
+ if [[ $message == *04* || $message == *07* ]]; then
+ if [[ $retry_count < 2 ]]; then
+ status="Error: could not process log message"
+ let "retry_count++"
+ else
+ status="OK"
+ retry_count=0
+ fi
+ else
+ status="OK"
+ fi
+
+ echo "<= $status" >> $outfile
+ echo "$status"
+ read line
+done
+
+exit 0
diff --git a/tests/testsuites/omprog-feedback-mt-bin.sh b/tests/testsuites/omprog-feedback-mt-bin.sh
new file mode 100755
index 0000000..97cf12f
--- /dev/null
+++ b/tests/testsuites/omprog-feedback-mt-bin.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+outfile=$RSYSLOG_OUT_LOG
+
+status="OK"
+echo $status
+
+retried=false
+
+read line
+while [[ -n "$line" ]]; do
+ message=${line//$'\n'}
+
+ if [[ $((RANDOM % 100)) < $1 ]]; then
+ status="Error: could not process log message"
+ retried=true
+ else
+ if [[ $retried == true ]]; then
+ echo "=> $message (retried)" >> $outfile
+ retried=false
+ else
+ echo "=> $message" >> $outfile
+ fi
+ status="OK"
+ fi
+
+ echo $status
+ read line
+done
+
+exit 0
diff --git a/tests/testsuites/omprog-feedback-timeout-bin.sh b/tests/testsuites/omprog-feedback-timeout-bin.sh
new file mode 100755
index 0000000..fa1565c
--- /dev/null
+++ b/tests/testsuites/omprog-feedback-timeout-bin.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+outfile=$RSYSLOG_OUT_LOG
+
+echo "Starting" >> $outfile
+echo "<= OK" >> $outfile
+echo "OK"
+
+just_started=true
+
+read line
+while [[ -n "$line" ]]; do
+ message=${line//$'\n'}
+ echo "=> $message" >> $outfile
+
+ if [[ $message == *02* ]]; then
+ # Test partial reads from pipe
+ echo "<= OK" >> $outfile
+ printf 'O'
+ printf 'K'
+ printf '\n'
+ elif [[ $message == *04* ]]; then
+ if [[ $just_started == false ]]; then
+ # Force a restart due to 'confirmTimeout' (2 seconds) exceeded
+ echo "<= (timeout)" >> $outfile
+ ./msleep 10000
+ else
+ # When the message is retried (just after restart), confirm it correctly
+ echo "<= OK" >> $outfile
+ echo "OK"
+ fi
+ elif [[ $message == *07* ]]; then
+ # Test keep-alive feature for long-running processing (more than 2 seconds)
+ echo "<= ........OK" >> $outfile
+ for i in {1..8}; do
+ ./msleep 500
+ printf '.'
+ done
+ printf 'OK\n'
+ else
+ echo "<= OK" >> $outfile
+ echo "OK"
+ fi
+
+ just_started=false
+ read line
+done
+
+exit 0
diff --git a/tests/testsuites/omprog-output-capture-bin.sh b/tests/testsuites/omprog-output-capture-bin.sh
new file mode 100755
index 0000000..1794cde
--- /dev/null
+++ b/tests/testsuites/omprog-output-capture-bin.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+echo "[stdout] Starting"
+>&2 echo "[stderr] Starting"
+
+read log_line
+while [[ -n "$log_line" ]]; do
+ echo "[stdout] Received $log_line"
+ >&2 echo "[stderr] Received $log_line"
+ read log_line
+done
+
+echo "[stdout] Terminating normally"
+>&2 echo "[stderr] Terminating normally"
+
+exit 0
diff --git a/tests/testsuites/omprog-output-capture-mt-bin.py b/tests/testsuites/omprog-output-capture-mt-bin.py
new file mode 100755
index 0000000..22cb553
--- /dev/null
+++ b/tests/testsuites/omprog-output-capture-mt-bin.py
@@ -0,0 +1,35 @@
+# call this via "python[3] script name"
+
+import sys
+import os
+
+lineLength = int(sys.argv[1])
+linePrefix = "[{0:09d}] ".format(os.getpid())
+
+logLine = sys.stdin.readline()
+while logLine:
+ logLine = logLine.strip()
+ numRepeats = int(lineLength / len(logLine))
+
+ lineToStdout = (linePrefix + "[stdout] " + logLine*numRepeats)[:lineLength]
+ lineToStderr = (linePrefix + "[stderr] " + logLine*numRepeats)[:lineLength]
+
+ sys.stdout.write(lineToStdout + "\n")
+ sys.stderr.write(lineToStderr + "\n")
+
+ # Flush stdout. In both Python 2 and Python 3, stdout is block-buffered when
+ # redirected to a file/pipe. But be want each line to be written immediately,
+ # because multiple processes are writing to the same pipe, and we do not want
+ # lines to appear intermingled in the output file. (The flush will cause a
+ # single 'write' syscall, since the size of the block buffer is generally
+ # greater than PIPE_BUF.)
+ sys.stdout.flush()
+
+ # Flush stderr. This is not necessary in Python 2, since stderr is unbuffered
+ # (and therefore each write will be written immediately and atomically to the
+ # pipe). However, in Python 3 stderr is block-buffered when redirected to a
+ # file/pipe. (Note: in future versions of Python 3, stderr could change to
+ # line-buffered; see https://bugs.python.org/issue13601.)
+ sys.stderr.flush()
+
+ logLine = sys.stdin.readline()
diff --git a/tests/testsuites/omprog-restart-terminated-bin.sh b/tests/testsuites/omprog-restart-terminated-bin.sh
new file mode 100755
index 0000000..2c2b2cc
--- /dev/null
+++ b/tests/testsuites/omprog-restart-terminated-bin.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+outfile=$RSYSLOG_OUT_LOG
+terminate=false
+
+function handle_sigusr1 {
+ echo "Received SIGUSR1, will terminate after the next message" >> $outfile
+ >&2 echo "[stderr] Received SIGUSR1, will terminate after the next message"
+ terminate=true
+}
+trap "handle_sigusr1" SIGUSR1
+
+function handle_sigterm {
+ echo "Received SIGTERM, terminating" >> $outfile
+ >&2 echo "[stderr] Received SIGTERM, terminating"
+ exit 1
+}
+trap "handle_sigterm" SIGTERM
+
+echo "Starting" >> $outfile
+
+# Write also to stderr (useful for testing the 'output' setting)
+>&2 echo "[stderr] Starting"
+
+# Tell rsyslog we are ready to start processing messages
+echo "OK"
+
+read log_line
+while [[ -n "$log_line" ]]; do
+ echo "Received $log_line" >> $outfile
+ >&2 echo "[stderr] Received $log_line"
+
+ if [[ $terminate == true ]]; then
+ # Terminate prematurely by closing pipe, without confirming the message
+ echo "Terminating without confirming the last message" >> $outfile
+ >&2 echo "[stderr] Terminating without confirming the last message"
+ exit 0
+ fi
+
+ # Tell rsyslog we are ready to process the next message
+ echo "OK"
+
+ read log_line
+done
+
+echo "Terminating normally" >> $outfile
+>&2 echo "[stderr] Terminating normally"
+
+exit 0
diff --git a/tests/testsuites/omprog-single-instance-bin.sh b/tests/testsuites/omprog-single-instance-bin.sh
new file mode 100755
index 0000000..bde73da
--- /dev/null
+++ b/tests/testsuites/omprog-single-instance-bin.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+outfile=$RSYSLOG_OUT_LOG
+
+# This line should appear only once in the output file for the test to pass:
+echo "Starting" >> $outfile
+
+# Write also to stderr (useful for testing the 'output' setting)
+>&2 echo "[stderr] Starting"
+
+echo "OK"
+
+read line
+while [[ -n "$line" ]]; do
+ echo "Received $line" >> $outfile
+ >&2 echo "[stderr] Received $line"
+ echo "OK"
+ read line
+done
+
+# This line should appear only once in the output file for the test to pass:
+echo "Terminating" >> $outfile
+>&2 echo "[stderr] Terminating"
+
+exit 0
diff --git a/tests/testsuites/omprog-transactions-bin.sh b/tests/testsuites/omprog-transactions-bin.sh
new file mode 100755
index 0000000..a8be3e4
--- /dev/null
+++ b/tests/testsuites/omprog-transactions-bin.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+outfile=$RSYSLOG_OUT_LOG
+
+status="OK"
+echo "<= $status" >> $outfile
+echo $status
+
+in_transaction=false
+fail_on_commit=false
+retry_count=0
+
+read line
+while [[ -n "$line" ]]; do
+ message=${line//$'\n'}
+ echo "=> $message" >> $outfile
+
+ if [[ "$message" == "BEGIN TRANSACTION" ]]; then
+ in_transaction=true
+ status="OK"
+ elif [[ "$message" == "COMMIT TRANSACTION" ]]; then
+ in_transaction=false
+ if [[ $fail_on_commit == true ]]; then
+ status="Error: could not commit transaction"
+ fail_on_commit=false
+ else
+ status="OK"
+ fi
+ else
+ if [[ $in_transaction == true ]]; then
+ status="DEFER_COMMIT"
+ else
+ # Should not occur
+ status="Error: received a message out of a transaction"
+ fi
+ fi
+
+ # First command line argument ($1) indicates whether to test for negative
+ # cases. If --failed_messages is specified, an error is returned for certain
+ # messages, forcing them to be retried twice. If --failed_commits is
+ # specified, the error is returned when committing the transaction.
+ if [[ "$1" != "" && ($message == *04* || $message == *07*) ]]; then
+ if [[ $retry_count < 2 ]]; then
+ if [[ "$1" == "--failed_commits" ]]; then
+ fail_on_commit=true
+ else
+ status="Error: could not process log message"
+ fi
+ let "retry_count++"
+ else
+ retry_count=0
+ fi
+ fi
+
+ echo "<= $status" >> $outfile
+ echo $status
+ read line
+done
+
+exit 0
diff --git a/tests/testsuites/pgsql-basic.sql b/tests/testsuites/pgsql-basic.sql
new file mode 100644
index 0000000..8b589e2
--- /dev/null
+++ b/tests/testsuites/pgsql-basic.sql
@@ -0,0 +1,30 @@
+DROP DATABASE IF EXISTS syslogtest;
+CREATE DATABASE syslogtest;
+\c syslogtest
+
+CREATE TABLE systemevents (
+ ID serial not null primary key,
+ CustomerID bigint,
+ ReceivedAt timestamp without time zone NULL,
+ DeviceReportedTime timestamp without time zone NULL,
+ Facility smallint NULL,
+ Priority smallint NULL,
+ FromHost varchar(60) NULL,
+ Message text,
+ NTSeverity int NULL,
+ Importance int NULL,
+ EventSource varchar(60),
+ EventUser varchar(60) NULL,
+ EventCategory int NULL,
+ EventID int NULL,
+ EventBinaryData text NULL,
+ MaxAvailable int NULL,
+ CurrUsage int NULL,
+ MinUsage int NULL,
+ MaxUsage int NULL,
+ InfoUnitID int NULL ,
+ SysLogTag varchar(60),
+ EventLogType varchar(60),
+ GenericFileName VarChar(60),
+ SystemID int NULL
+);
diff --git a/tests/testsuites/pgsql-select-msg.sql b/tests/testsuites/pgsql-select-msg.sql
new file mode 100644
index 0000000..5210aed
--- /dev/null
+++ b/tests/testsuites/pgsql-select-msg.sql
@@ -0,0 +1 @@
+SELECT substring(Message,9,8) FROM systemevents;
diff --git a/tests/testsuites/pgsql-select-syslogtag.sql b/tests/testsuites/pgsql-select-syslogtag.sql
new file mode 100644
index 0000000..8c0f1ee
--- /dev/null
+++ b/tests/testsuites/pgsql-select-syslogtag.sql
@@ -0,0 +1 @@
+select substring(SysLogTag,9,8) from SystemEvents;
diff --git a/tests/testsuites/pmnormalize_basic.rulebase b/tests/testsuites/pmnormalize_basic.rulebase
new file mode 100644
index 0000000..f7eb2b8
--- /dev/null
+++ b/tests/testsuites/pmnormalize_basic.rulebase
@@ -0,0 +1 @@
+rule=:<%pri:number%> %hostname:word% %syslogtag:char-to:\x3a%: is no longer listening on %fromhost-ip:ipv4% %msg:rest%
diff --git a/tests/testsuites/regex_input b/tests/testsuites/regex_input
new file mode 100644
index 0000000..ed1fbd2
--- /dev/null
+++ b/tests/testsuites/regex_input
@@ -0,0 +1 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:http host ports are 192.168.1.2:80, 192.168.1.3, 192.168.1.4:443, 192.168.1.5 etc
diff --git a/tests/testsuites/spframingfix.testdata b/tests/testsuites/spframingfix.testdata
new file mode 100644
index 0000000..d97a3da
--- /dev/null
+++ b/tests/testsuites/spframingfix.testdata
@@ -0,0 +1,20 @@
+<181>00
+ <181>01
+<181>02
+ <181>03
+ <181>04
+ <181>05
+<181>06
+<181>07
+<181>08
+<181>09
+<181>10
+ <181>11
+ <181>12
+ <181>13
+ <181>14
+<181>15
+ <181>16
+<181>17
+ <181>18
+<181>19
diff --git a/tests/testsuites/stop_when_array_has_elem_input b/tests/testsuites/stop_when_array_has_elem_input
new file mode 100644
index 0000000..6fddc95
--- /dev/null
+++ b/tests/testsuites/stop_when_array_has_elem_input
@@ -0,0 +1,3 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:@cee:{"foo": ["abc0", "def1", "ghi2"]}
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:@cee:{"foo": ["xyz0", "zab1", "abc2"]}
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:@cee:{"foo": ["abc2", "def1", "ghi0"]}
diff --git a/tests/testsuites/tokenized_input b/tests/testsuites/tokenized_input
new file mode 100644
index 0000000..8825673
--- /dev/null
+++ b/tests/testsuites/tokenized_input
@@ -0,0 +1,5 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:10.20.30.40, 50.60.70.80, 90.100.110.120, 130.140.150.160
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:local ips are 192.168.1.2, 192.168.1.3, 192.168.1.4
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:10.20.30.40, 50.60.70.80, 190.200.210.220 are external ips
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:for foo@localhost path was /bin:/usr/local/bin:/usr/bin
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005:comma separated list of colon separated numbers: 10, 20 : 30#40#50 : 60#70#80, 90 : 100
diff --git a/tests/testsuites/valid.conf b/tests/testsuites/valid.conf
new file mode 100644
index 0000000..250f054
--- /dev/null
+++ b/tests/testsuites/valid.conf
@@ -0,0 +1,3 @@
+# This is an invalid config file that shall trigger an exit code
+# with the config verification run
+*.* /tmp/data.log
diff --git a/tests/testsuites/variable_leading_underscore.conf b/tests/testsuites/variable_leading_underscore.conf
new file mode 100644
index 0000000..6279345
--- /dev/null
+++ b/tests/testsuites/variable_leading_underscore.conf
@@ -0,0 +1,2 @@
+set $.foo = $!_FOO;
+*.* /dev/null # we need to have one action, else rsyslog aborts for that reason
diff --git a/tests/testsuites/wrap3_input b/tests/testsuites/wrap3_input
new file mode 100644
index 0000000..18aa3cb
--- /dev/null
+++ b/tests/testsuites/wrap3_input
@@ -0,0 +1 @@
+<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: a abcbcdefbcdefb has bcdefbc
diff --git a/tests/testsuites/x.509/ca-key.pem b/tests/testsuites/x.509/ca-key.pem
new file mode 100644
index 0000000..9234024
--- /dev/null
+++ b/tests/testsuites/x.509/ca-key.pem
@@ -0,0 +1,182 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:a1:0b:0c:e4:ad:a2:f6:bf:d4:85:01:8d:d6:0f:56
+ ae:e9:c4:42:49:aa:ab:80:2f:f9:71:e7:30:cc:60:6e
+ 9b:49:e3:94:ee:24:99:49:08:e4:6e:20:d5:cc:13:b5
+ 7a:9c:99:38:75:ec:42:9a:1e:50:45:a2:e8:27:1f:92
+ 59:74:31:66:2a:93:88:a7:8a:1d:00:29:79:ba:e4:f9
+ 27:59:51:87:a9:6c:3b:25:6a:f5:7d:21:aa:9f:6a:7e
+ 39:f5:ae:b9:fb:5d:f2:e4:f6:2f:7e:a2:bd:3f:88:b2
+ b6:99:e8:26:53:96:54:5f:aa:4d:a6:82:9a:19:e2:c1
+ 97:80:9e:8a:28:aa:75:a5:1e:c8:62:bc:60:a4:24:b3
+ 1f:f4:cd:d7:96:6f:4e:18:a7:ec:c7:21:d7:5c:1a:81
+ 80:c7:cf:33:7f:de:28:9c:94:04:4a:c5:4e:9f:5c:86
+ de:c1:8c:ee:b8:5f:bc:e1:c3:2c:62:78:7e:51:3e:d7
+ 0c:3c:0f:aa:d9:65:c8:ba:0f:86:d8:85:f0:35:6e:98
+ 91:c2:c5:37:50:82:e0:8a:75:15:a5:f6:cc:9f:e5:ba
+ 7f:6b:3e:0a:ad:1d:6e:24:33:6b:49:5f:f9:2d:ab:2b
+ ee:dc:1f:ee:33:f6:5b:6a:03:4e:78:07:6f:c9:3e:e3
+ 4a:6f:07:f7:94:ba:1a:6c:63:56:bb:8e:d3:09:fc:b3
+ 68:35:1b:ed:8e:f4:08:54:6b:61:f9:0d:e2:90:f9:cb
+ e6:7c:df:c2:07:f3:b4:4a:26:2a:21:e6:ad:9c:79:55
+ f9:a7:23:6f:f1:79:a4:32:eb:d6:60:3a:e7:8d:54:e7
+ 5f:b4:34:7c:df:d3:ea:1f:1f:55:32:29:96:88:e5:81
+ 5f:33:da:d3:dc:ac:91:34:33:86:3a:ee:74:80:81:85
+ fb:bf:60:2d:99:ca:01:3c:c2:f9:49:a8:ab:ce:ae:5a
+ a6:29:63:6f:45:a6:e4:a4:8d:c1:76:76:78:0c:fd:9d
+ 3b:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 00:89:fd:ca:02:78:b6:56:f0:70:cd:b7:53:2d:c4:de
+ e5:e9:f0:fd:4b:da:2e:32:1c:e9:85:2c:30:a8:2f:49
+ 17:4e:ec:ef:44:4f:9f:f8:f0:e1:ab:6b:ff:46:6a:ec
+ ea:2f:1d:2b:40:00:3d:e1:89:70:06:fb:5c:29:89:e8
+ 01:36:8a:cd:9c:55:e6:96:88:c5:e8:c9:a1:40:ff:ca
+ 6e:69:1e:6f:3c:41:3d:3d:06:b5:6b:8f:59:80:57:e3
+ e9:0e:17:b5:cd:29:e7:63:41:7f:d8:e6:e1:7a:7b:4b
+ 87:23:c1:c4:75:83:2e:b0:fa:60:a6:f8:e9:ca:9c:7e
+ 7d:ae:fc:2a:2e:46:41:a0:47:0c:35:6e:6c:f0:b9:71
+ b3:44:34:cd:32:5e:15:71:13:12:d4:5e:af:06:80:bf
+ ce:f5:67:1a:1d:ca:e2:c9:a8:1b:35:66:73:c4:21:a8
+ 7f:5f:21:bf:bb:c4:6d:38:95:e0:86:4f:f1:0c:f4:e7
+ 96:7b:da:9e:95:7f:93:ca:96:ea:07:4f:13:52:5d:39
+ 99:42:44:b5:a3:11:af:6e:62:a1:c9:43:6d:24:69:13
+ 8a:62:ea:76:ae:7e:29:ef:c1:7e:a3:6e:b1:a8:71:9d
+ 3e:1a:40:03:16:b8:a5:a5:df:b3:c0:6b:d1:7b:fd:91
+ e0:5b:30:d3:22:49:74:c3:ee:ca:b1:85:c9:9a:c5:8b
+ 45:3e:c3:75:f9:0c:ee:41:2d:12:f6:98:41:d4:ea:dd
+ d3:89:d4:7f:01:b0:19:3b:34:30:16:16:03:d9:74:9f
+ 4a:ba:71:59:1f:9b:7e:ee:ed:5f:c1:ec:11:38:bb:04
+ a6:5e:b8:e3:0f:61:e7:92:39:e3:a9:5f:ab:31:f5:2d
+ 0c:55:f2:70:c4:25:75:ba:98:50:26:82:4e:e8:94:db
+ 21:2c:6c:31:5c:e6:e5:65:8c:31:48:cb:98:73:1a:61
+ 96:a2:dd:27:f8:30:54:6a:9e:19:26:77:13:be:ca:d3
+ a1:
+
+prime1:
+ 00:d4:9d:19:0c:c4:68:92:2c:4f:ab:ab:04:d0:4b:6c
+ 3c:b3:df:59:26:f6:28:e8:85:27:2b:b9:0a:7b:d7:52
+ ab:90:d9:3d:bc:38:34:ad:e6:b6:e9:1a:f8:a4:ab:cf
+ 4f:94:92:6c:a9:38:c3:ee:19:1f:4c:95:e8:80:c3:50
+ 1d:bb:1a:41:20:03:1a:c1:e9:7a:ff:e3:f7:1d:3f:12
+ da:09:99:de:50:33:8c:ee:37:6e:c9:e3:aa:ec:9d:e0
+ 84:5f:97:1b:48:cf:b3:d1:99:91:97:05:69:b5:47:20
+ fa:43:d8:01:bb:dc:95:a8:3b:77:d3:5d:25:31:cd:9b
+ 01:90:22:1c:92:c6:e5:e2:09:51:42:7d:0c:70:08:25
+ c5:9c:b7:71:1e:96:f1:df:c9:f0:aa:e2:52:4f:32:e1
+ f7:76:ca:fb:6c:6a:c7:c1:22:54:45:c9:6f:3c:a7:b5
+ f6:7d:c7:f7:e0:09:c8:36:59:d2:a8:09:7b:11:b6:3c
+ af:
+
+prime2:
+ 00:c1:e7:eb:18:5e:4d:3c:7f:b9:16:bf:d8:ce:9f:b7
+ c3:6a:a0:fa:0b:64:68:20:c5:18:d1:c8:13:d5:82:24
+ 8f:b7:5c:50:64:64:3a:8c:25:cc:71:21:79:ba:74:34
+ 16:56:6c:3d:4b:60:1e:2c:83:88:51:d4:76:61:57:5a
+ 12:83:3c:67:6e:09:c5:74:27:fd:64:af:46:a2:09:41
+ 9c:95:a1:cd:9d:86:14:29:69:28:a6:88:c3:71:9b:ac
+ a9:94:1e:df:10:78:f1:ec:30:46:95:9c:58:bf:7f:1e
+ 55:a6:3c:14:24:8f:9f:d3:97:3a:b8:cb:82:8c:c7:a9
+ 49:5b:20:5a:ae:f3:20:b3:e5:e7:2e:e1:17:02:57:c5
+ f9:bf:68:10:74:6c:69:7b:55:ad:6b:58:f8:13:33:d1
+ 85:96:e0:96:d8:e3:6f:79:77:f3:17:b0:7a:02:81:16
+ 6e:55:23:65:10:90:90:0b:6e:5b:cb:3b:cc:6e:83:03
+ 35:
+
+coefficient:
+ 46:d5:f1:79:c7:d6:70:c2:eb:9b:fd:12:0a:53:b9:54
+ 60:14:e0:33:3b:ab:41:71:ac:2a:51:12:b3:87:ad:98
+ 9e:a9:ac:b4:6d:b5:02:4d:1e:b2:e5:fe:76:e5:8c:c1
+ cb:60:0e:f3:76:77:be:e1:51:86:f1:9e:ae:c0:d9:78
+ 3c:7a:c0:b6:02:75:dc:21:cf:d0:bc:fe:fa:34:33:a1
+ 1a:a6:cf:7d:27:cc:d7:46:46:f0:8f:9d:31:4d:cf:78
+ ec:15:6a:6f:64:18:24:04:65:b7:bc:58:0d:1c:35:3c
+ 16:e3:2d:f5:e0:13:64:a2:44:8c:4a:34:54:ab:23:4e
+ fd:01:3c:01:7d:87:5b:5a:16:ce:c8:b8:05:bf:74:ea
+ b5:94:77:23:1b:2d:33:55:c3:a2:e0:b7:a4:28:be:81
+ ac:f0:63:d3:28:b7:01:b9:4c:03:aa:d1:d1:d1:36:2a
+ 99:1d:93:ac:ea:da:66:fb:7e:97:d3:bf:d2:b0:92:a0
+
+
+exp1:
+ 7f:2e:76:44:97:dc:c1:cb:b5:e0:c7:cd:7a:58:13:a8
+ 00:25:13:ac:65:c5:b4:c9:a9:d3:d2:bd:bd:b4:e1:23
+ f5:e2:ad:b6:40:9c:ea:85:bf:56:93:a6:b6:c2:7b:a1
+ 6c:0b:66:ea:97:25:44:f1:4c:32:c0:dd:b2:e0:a2:b5
+ 16:2e:2f:54:d9:e6:90:a6:7c:c8:43:72:97:d1:1a:12
+ c9:79:7c:6d:d7:58:6f:4b:43:7f:8b:2b:bc:9c:f8:27
+ d7:12:89:e4:b5:32:28:a8:47:59:e2:88:08:43:43:2b
+ d1:97:8d:f9:f5:8a:a4:76:e6:47:ce:49:28:90:88:2f
+ 98:2b:7f:92:21:5e:74:27:04:af:d4:23:b3:84:7c:2b
+ c8:82:47:2d:78:37:b9:99:8f:d8:78:c7:a9:ce:93:33
+ 37:a1:56:62:d5:41:26:7b:c5:93:75:5a:90:1a:f6:93
+ 3b:4c:7a:2f:4f:4a:af:90:6d:9d:cd:06:0c:63:49:cb
+
+
+exp2:
+ 4e:2c:e8:55:7c:bf:7a:e2:ab:86:86:76:2c:67:ac:38
+ b6:e6:8b:a8:c8:24:4b:01:eb:8d:b8:32:76:e3:ef:45
+ 99:d1:38:00:21:80:91:3c:33:fe:70:56:99:5b:7c:1c
+ 7d:5f:4a:1e:f7:73:72:d2:dc:c4:d0:f9:a1:29:0c:81
+ 66:33:96:27:80:fd:00:65:96:fd:5e:c5:05:52:e2:06
+ f5:34:b4:a7:0b:85:59:64:b2:24:e2:02:99:ec:ff:61
+ a6:fc:03:46:aa:dc:2e:33:10:62:05:14:aa:af:df:54
+ fc:9e:40:28:b5:56:e4:81:96:05:26:d7:4d:56:b9:e3
+ 7f:3f:be:0f:c6:a9:aa:9d:c7:e4:d8:8e:e4:3c:ea:ee
+ 53:c2:ea:cf:65:5d:e9:81:93:57:32:19:61:f4:84:46
+ 6d:9b:c2:75:52:cc:80:96:61:85:6d:7a:e3:43:93:fd
+ 8b:89:a7:97:54:11:1e:ea:b1:4b:70:a2:6c:f3:98:f9
+
+
+
+Public Key PIN:
+ pin-sha256:3cQAkiO2zLPAa/Tawzz/iqD5XAly2f+6m0f1OwppO8w=
+Public Key ID:
+ sha256:ddc4009223b6ccb3c06bf4dac33cff8aa0f95c0972d9ffba9b47f53b0a693bcc
+ sha1:b09f67332c8888891f4462749d25ffc006135dd6
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4wIBAAKCAYEAoQsM5K2i9r/UhQGN1g9WrunEQkmqq4Av+XHnMMxgbptJ45Tu
+JJlJCORuINXME7V6nJk4dexCmh5QRaLoJx+SWXQxZiqTiKeKHQApebrk+SdZUYep
+bDslavV9Iaqfan459a65+13y5PYvfqK9P4iytpnoJlOWVF+qTaaCmhniwZeAnooo
+qnWlHshivGCkJLMf9M3Xlm9OGKfsxyHXXBqBgMfPM3/eKJyUBErFTp9cht7BjO64
+X7zhwyxieH5RPtcMPA+q2WXIug+G2IXwNW6YkcLFN1CC4Ip1FaX2zJ/lun9rPgqt
+HW4kM2tJX/ktqyvu3B/uM/ZbagNOeAdvyT7jSm8H95S6GmxjVruO0wn8s2g1G+2O
+9AhUa2H5DeKQ+cvmfN/CB/O0SiYqIeatnHlV+acjb/F5pDLr1mA6541U51+0NHzf
+0+ofH1UyKZaI5YFfM9rT3KyRNDOGOu50gIGF+79gLZnKATzC+Umoq86uWqYpY29F
+puSkjcF2dngM/Z07AgMBAAECggGBAIn9ygJ4tlbwcM23Uy3E3uXp8P1L2i4yHOmF
+LDCoL0kXTuzvRE+f+PDhq2v/Rmrs6i8dK0AAPeGJcAb7XCmJ6AE2is2cVeaWiMXo
+yaFA/8puaR5vPEE9PQa1a49ZgFfj6Q4Xtc0p52NBf9jm4Xp7S4cjwcR1gy6w+mCm
++OnKnH59rvwqLkZBoEcMNW5s8Llxs0Q0zTJeFXETEtRerwaAv871ZxodyuLJqBs1
+ZnPEIah/XyG/u8RtOJXghk/xDPTnlnvanpV/k8qW6gdPE1JdOZlCRLWjEa9uYqHJ
+Q20kaROKYup2rn4p78F+o26xqHGdPhpAAxa4paXfs8Br0Xv9keBbMNMiSXTD7sqx
+hcmaxYtFPsN1+QzuQS0S9phB1Ord04nUfwGwGTs0MBYWA9l0n0q6cVkfm37u7V/B
+7BE4uwSmXrjjD2HnkjnjqV+rMfUtDFXycMQldbqYUCaCTuiU2yEsbDFc5uVljDFI
+y5hzGmGWot0n+DBUap4ZJncTvsrToQKBwQDUnRkMxGiSLE+rqwTQS2w8s99ZJvYo
+6IUnK7kKe9dSq5DZPbw4NK3mtuka+KSrz0+UkmypOMPuGR9MleiAw1AduxpBIAMa
+wel6/+P3HT8S2gmZ3lAzjO43bsnjquyd4IRflxtIz7PRmZGXBWm1RyD6Q9gBu9yV
+qDt3010lMc2bAZAiHJLG5eIJUUJ9DHAIJcWct3EelvHfyfCq4lJPMuH3dsr7bGrH
+wSJURclvPKe19n3H9+AJyDZZ0qgJexG2PK8CgcEAwefrGF5NPH+5Fr/Yzp+3w2qg
++gtkaCDFGNHIE9WCJI+3XFBkZDqMJcxxIXm6dDQWVmw9S2AeLIOIUdR2YVdaEoM8
+Z24JxXQn/WSvRqIJQZyVoc2dhhQpaSimiMNxm6yplB7fEHjx7DBGlZxYv38eVaY8
+FCSPn9OXOrjLgozHqUlbIFqu8yCz5ecu4RcCV8X5v2gQdGxpe1Wta1j4EzPRhZbg
+ltjjb3l38xewegKBFm5VI2UQkJALblvLO8xugwM1AoHAfy52RJfcwcu14MfNelgT
+qAAlE6xlxbTJqdPSvb204SP14q22QJzqhb9Wk6a2wnuhbAtm6pclRPFMMsDdsuCi
+tRYuL1TZ5pCmfMhDcpfRGhLJeXxt11hvS0N/iyu8nPgn1xKJ5LUyKKhHWeKICEND
+K9GXjfn1iqR25kfOSSiQiC+YK3+SIV50JwSv1COzhHwryIJHLXg3uZmP2HjHqc6T
+MzehVmLVQSZ7xZN1WpAa9pM7THovT0qvkG2dzQYMY0nLAoHATizoVXy/euKrhoZ2
+LGesOLbmi6jIJEsB6424Mnbj70WZ0TgAIYCRPDP+cFaZW3wcfV9KHvdzctLcxND5
+oSkMgWYzlieA/QBllv1exQVS4gb1NLSnC4VZZLIk4gKZ7P9hpvwDRqrcLjMQYgUU
+qq/fVPyeQCi1VuSBlgUm101WueN/P74Pxqmqncfk2I7kPOruU8Lqz2Vd6YGTVzIZ
+YfSERm2bwnVSzICWYYVteuNDk/2LiaeXVBEe6rFLcKJs85j5AoHARtXxecfWcMLr
+m/0SClO5VGAU4DM7q0FxrCpRErOHrZieqay0bbUCTR6y5f525YzBy2AO83Z3vuFR
+hvGersDZeDx6wLYCddwhz9C8/vo0M6Eaps99J8zXRkbwj50xTc947BVqb2QYJARl
+t7xYDRw1PBbjLfXgE2SiRIxKNFSrI079ATwBfYdbWhbOyLgFv3TqtZR3IxstM1XD
+ouC3pCi+gazwY9MotwG5TAOq0dHRNiqZHZOs6tpm+36X07/SsJKg
+-----END RSA PRIVATE KEY-----
diff --git a/tests/testsuites/x.509/ca.pem b/tests/testsuites/x.509/ca.pem
new file mode 100644
index 0000000..430e5c2
--- /dev/null
+++ b/tests/testsuites/x.509/ca.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEiDCCAvCgAwIBAgIIXBeb1iWItcgwDQYJKoZIhvcNAQELBQAwRDERMA8GA1UE
+AxMIc29tZU5hbWUxEDAOBgNVBAsTB3JzeXNsb2cxEDAOBgNVBAoTB1NvbWVPcmcx
+CzAJBgNVBAYTAlVTMCAXDTE4MTIxNzEyNTEzNVoYDzIxMTgxMTIzMTI1MTUwWjBE
+MREwDwYDVQQDEwhzb21lTmFtZTEQMA4GA1UECxMHcnN5c2xvZzEQMA4GA1UEChMH
+U29tZU9yZzELMAkGA1UEBhMCVVMwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGK
+AoIBgQChCwzkraL2v9SFAY3WD1au6cRCSaqrgC/5cecwzGBum0njlO4kmUkI5G4g
+1cwTtXqcmTh17EKaHlBFougnH5JZdDFmKpOIp4odACl5uuT5J1lRh6lsOyVq9X0h
+qp9qfjn1rrn7XfLk9i9+or0/iLK2megmU5ZUX6pNpoKaGeLBl4CeiiiqdaUeyGK8
+YKQksx/0zdeWb04Yp+zHIddcGoGAx88zf94onJQESsVOn1yG3sGM7rhfvOHDLGJ4
+flE+1ww8D6rZZci6D4bYhfA1bpiRwsU3UILginUVpfbMn+W6f2s+Cq0dbiQza0lf
++S2rK+7cH+4z9ltqA054B2/JPuNKbwf3lLoabGNWu47TCfyzaDUb7Y70CFRrYfkN
+4pD5y+Z838IH87RKJioh5q2ceVX5pyNv8XmkMuvWYDrnjVTnX7Q0fN/T6h8fVTIp
+lojlgV8z2tPcrJE0M4Y67nSAgYX7v2AtmcoBPML5Sairzq5apiljb0Wm5KSNwXZ2
+eAz9nTsCAwEAAaN8MHowDwYDVR0TAQH/BAUwAwEB/zBIBgNVHREEQTA/ghNzb21l
+b25lQGV4YW1wbGUubmV0ghNzb21lb25lQGV4YW1wbGUubmV0gRNzb21lb25lQGV4
+YW1wbGUubmV0MB0GA1UdDgQWBBSwn2czLIiIiR9EYnSdJf/ABhNd1jANBgkqhkiG
+9w0BAQsFAAOCAYEAl6nIgBHMX8rnAC054xx/aQcXazrv89KyEp0ydzBwJQOTei7I
+UGWQIRkSLL+CtrGhcLPQpTzAQn5NDo4ayinAtlPtP8MYcMBv13ZBJXLSqRfrTM04
+wkEbsWuCp+c/fU14E+QYSk4AwpoUdQeqmdM60KAoHNn+BaHGJRhRGOY9A8hfQQ5L
+S2TpJ+suJuHafNjr9vvhlqTSefCfENV40Ie1nwHCbqNZdDZel1iQBmdI7WJG7uTI
+OrSOPepYzOAYKQ+PWKMvZuzBc6ei/lcIpPHksWxK7nY35izSHjepMLGqH0/XZ51i
+wN55slw9agg5eCq/zL/+Ebu7+yub8JhA9D4pgT5nBp8LtQPOIKnkVlFookjfyO8/
+dWsjGnhT9RNbDUQg7Y7spTWPT7wqOmQchEvQt+x96BHq4SLe88HnTpBk2Cb370jq
+QQFW6s9vwo9PjOafOkyqYsiBuuCFxT80GegBlaipDNqLYhJ1fJAdQtRtFgogqpeS
+thWJZzNJeHyZSpah
+-----END CERTIFICATE-----
diff --git a/tests/testsuites/x.509/ca.srl b/tests/testsuites/x.509/ca.srl
new file mode 100644
index 0000000..09f81ec
--- /dev/null
+++ b/tests/testsuites/x.509/ca.srl
@@ -0,0 +1 @@
+0D7B5949C4431CF8E2E1D6D9F4694C044A80B748
diff --git a/tests/testsuites/x.509/client-cert-new.pem b/tests/testsuites/x.509/client-cert-new.pem
new file mode 100644
index 0000000..e92ab86
--- /dev/null
+++ b/tests/testsuites/x.509/client-cert-new.pem
@@ -0,0 +1,102 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 4 (0x4)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=someName, OU=rsyslog, O=SomeOrg, C=US
+ Validity
+ Not Before: Jul 6 13:52:50 2023 GMT
+ Not After : Jun 12 13:52:50 2123 GMT
+ Subject: C=US, ST=CA, O=SomeComp, OU=SomeUnit, CN=rsyslog/emailAddress=alorbach@adiscon.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (3072 bit)
+ Modulus:
+ 00:9d:91:da:d8:2e:3d:9d:ae:85:c3:c5:a7:f6:a4:
+ 66:f8:c8:91:91:b8:70:20:dc:ed:e8:23:ca:53:f7:
+ b8:52:43:f3:a7:eb:fb:df:8a:3b:2c:b0:13:fa:62:
+ d3:a1:53:a4:51:71:1f:68:d9:fd:bc:39:4a:fb:c9:
+ 6a:df:f3:88:84:b0:80:bc:c0:f5:1b:42:11:f6:4c:
+ 1a:d8:2c:62:0b:5d:50:64:30:9a:d3:db:c1:d5:7f:
+ 39:53:e4:bd:e8:1e:04:9d:c9:12:e0:e4:57:29:29:
+ 01:b9:f1:e5:bc:74:a6:e7:4b:61:e6:67:5c:6c:4e:
+ ee:ee:22:0c:1b:14:6d:e8:0c:6f:ee:ee:c3:b8:dd:
+ df:15:ed:7a:96:5b:cc:85:e5:e3:50:c4:ce:2b:bf:
+ b6:37:e6:20:fc:6e:45:7e:09:bd:84:7a:af:07:27:
+ f4:99:23:41:df:36:d8:29:31:a0:96:84:2f:fd:45:
+ 2e:d4:b4:f9:fa:dc:8f:23:c0:e0:06:ad:ad:0a:72:
+ da:f4:3b:a1:cb:d6:a6:3b:ec:46:c4:95:f2:71:a5:
+ ad:08:1f:e7:06:18:0e:db:80:51:96:ba:24:f6:64:
+ 02:6b:d3:f0:76:01:34:3a:72:02:e9:cb:d0:aa:62:
+ 51:0c:8f:83:be:c0:47:99:d2:92:72:ed:53:a5:49:
+ 05:d4:c9:a1:f4:4d:de:12:9d:1a:c8:17:84:f3:a2:
+ 7c:67:47:82:4b:86:1e:73:86:e2:26:26:10:94:a3:
+ 99:9b:08:99:78:9d:3d:33:5d:85:c2:46:65:94:ab:
+ 70:b4:3b:c1:26:8b:11:b6:66:27:88:22:84:03:b5:
+ 08:45:32:8c:81:23:be:62:dc:6f:a0:aa:5e:9f:03:
+ f7:a7:f5:03:70:3c:78:09:d0:84:44:8c:19:af:76:
+ f7:93:fc:af:c6:fd:db:d9:4c:cb:20:79:44:71:cb:
+ e6:55:61:a9:7a:af:0b:a3:a6:ed:e9:a9:11:af:fa:
+ a3:5d:ac:97:e7:ef:2b:b6:a8:37
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 6E:15:7E:C4:62:2B:92:6D:22:EE:0C:E4:C5:36:29:38:16:62:BE:89
+ X509v3 Authority Key Identifier:
+ keyid:B0:9F:67:33:2C:88:88:89:1F:44:62:74:9D:25:FF:C0:06:13:5D:D6
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 64:b0:45:6b:0c:7c:2d:09:14:8e:78:93:85:ef:d2:31:aa:c3:
+ 59:2e:85:bf:29:e1:46:59:38:d4:fe:ea:c4:c1:83:a7:4a:1b:
+ 92:5e:e8:11:9c:21:48:9d:1e:cc:31:d8:31:00:72:fe:7b:c1:
+ 18:c4:f5:37:f3:3b:0e:1a:f6:3f:19:47:22:c9:87:01:e0:4c:
+ f4:5d:36:0a:87:46:42:fc:6c:ab:26:ff:7d:ca:2c:19:97:ca:
+ 25:fc:70:66:4e:49:86:3e:81:0f:ee:e2:5c:3b:69:07:8b:c2:
+ 52:09:46:d8:67:af:84:54:bb:4f:f3:e0:da:07:c5:64:56:2d:
+ fb:f9:55:13:53:1d:c6:78:63:40:22:23:4f:63:59:37:05:c7:
+ 46:b6:36:53:30:fe:9b:e6:01:0a:54:5b:be:1b:a4:72:c3:27:
+ 1b:c5:21:5d:d3:0c:06:56:d9:df:45:83:e7:06:6d:47:53:72:
+ ea:6c:e7:db:5e:bd:14:47:19:0c:18:13:73:6b:14:dc:29:6c:
+ c0:60:fa:4c:02:74:45:e7:8d:12:bd:1f:cb:77:2c:72:19:ef:
+ e8:85:5c:cf:77:04:b7:d4:08:a8:7e:d1:1d:20:7b:76:27:ca:
+ 8a:5a:2a:a5:e7:15:6c:2d:50:9c:c2:b4:83:45:c2:f7:a5:f0:
+ 6b:d5:45:6b:88:4c:db:00:26:2f:8e:0a:3c:42:4e:0c:64:18:
+ 41:a0:6b:4b:d0:78:89:b4:64:34:5b:76:cb:dd:b9:be:6e:28:
+ 82:ba:6e:11:99:86:88:b6:0d:22:2b:a6:eb:5f:0b:ca:77:5b:
+ 2e:28:b7:f3:96:c3:8c:9d:0d:2b:59:98:d4:20:87:3a:2e:f4:
+ e3:bf:a2:ff:67:4f:3f:1e:ce:ec:59:76:5a:67:81:ba:44:96:
+ 29:af:05:ce:55:02:b4:d6:68:f0:25:61:8c:91:83:03:fd:e4:
+ 2c:06:91:b4:32:d8:5b:47:d6:20:55:44:a6:0c:9b:97:bb:94:
+ 66:25:8c:35:e0:32
+-----BEGIN CERTIFICATE-----
+MIIEszCCAxugAwIBAgIBBDANBgkqhkiG9w0BAQsFADBEMREwDwYDVQQDEwhzb21l
+TmFtZTEQMA4GA1UECxMHcnN5c2xvZzEQMA4GA1UEChMHU29tZU9yZzELMAkGA1UE
+BhMCVVMwIBcNMjMwNzA2MTM1MjUwWhgPMjEyMzA2MTIxMzUyNTBaMHcxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJDQTERMA8GA1UECgwIU29tZUNvbXAxETAPBgNVBAsM
+CFNvbWVVbml0MRAwDgYDVQQDDAdyc3lzbG9nMSMwIQYJKoZIhvcNAQkBFhRhbG9y
+YmFjaEBhZGlzY29uLmNvbTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGB
+AJ2R2tguPZ2uhcPFp/akZvjIkZG4cCDc7egjylP3uFJD86fr+9+KOyywE/pi06FT
+pFFxH2jZ/bw5SvvJat/ziISwgLzA9RtCEfZMGtgsYgtdUGQwmtPbwdV/OVPkvege
+BJ3JEuDkVykpAbnx5bx0pudLYeZnXGxO7u4iDBsUbegMb+7uw7jd3xXtepZbzIXl
+41DEziu/tjfmIPxuRX4JvYR6rwcn9JkjQd822CkxoJaEL/1FLtS0+frcjyPA4Aat
+rQpy2vQ7ocvWpjvsRsSV8nGlrQgf5wYYDtuAUZa6JPZkAmvT8HYBNDpyAunL0Kpi
+UQyPg77AR5nSknLtU6VJBdTJofRN3hKdGsgXhPOifGdHgkuGHnOG4iYmEJSjmZsI
+mXidPTNdhcJGZZSrcLQ7wSaLEbZmJ4gihAO1CEUyjIEjvmLcb6CqXp8D96f1A3A8
+eAnQhESMGa9295P8r8b929lMyyB5RHHL5lVhqXqvC6Om7empEa/6o12sl+fvK7ao
+NwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdl
+bmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUbhV+xGIrkm0i7gzkxTYpOBZi
+vokwHwYDVR0jBBgwFoAUsJ9nMyyIiIkfRGJ0nSX/wAYTXdYwDQYJKoZIhvcNAQEL
+BQADggGBAGSwRWsMfC0JFI54k4Xv0jGqw1kuhb8p4UZZONT+6sTBg6dKG5Je6BGc
+IUidHswx2DEAcv57wRjE9TfzOw4a9j8ZRyLJhwHgTPRdNgqHRkL8bKsm/33KLBmX
+yiX8cGZOSYY+gQ/u4lw7aQeLwlIJRthnr4RUu0/z4NoHxWRWLfv5VRNTHcZ4Y0Ai
+I09jWTcFx0a2NlMw/pvmAQpUW74bpHLDJxvFIV3TDAZW2d9Fg+cGbUdTcups59te
+vRRHGQwYE3NrFNwpbMBg+kwCdEXnjRK9H8t3LHIZ7+iFXM93BLfUCKh+0R0ge3Yn
+yopaKqXnFWwtUJzCtINFwvel8GvVRWuITNsAJi+OCjxCTgxkGEGga0vQeIm0ZDRb
+dsvdub5uKIK6bhGZhoi2DSIrputfC8p3Wy4ot/OWw4ydDStZmNQghzou9OO/ov9n
+Tz8ezuxZdlpngbpElimvBc5VArTWaPAlYYyRgwP95CwGkbQy2FtH1iBVRKYMm5e7
+lGYljDXgMg==
+-----END CERTIFICATE-----
diff --git a/tests/testsuites/x.509/client-cert.pem b/tests/testsuites/x.509/client-cert.pem
new file mode 100644
index 0000000..abd9702
--- /dev/null
+++ b/tests/testsuites/x.509/client-cert.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEoTCCAwmgAwIBAgIIXBeg0SlsiUswDQYJKoZIhvcNAQELBQAwRDERMA8GA1UE
+AxMIc29tZU5hbWUxEDAOBgNVBAsTB3JzeXNsb2cxEDAOBgNVBAoTB1NvbWVPcmcx
+CzAJBgNVBAYTAlVTMCAXDTE4MTIxNzEzMTI1MFoYDzIxMTgxMTIzMTMxMjUzWjBY
+MRcwFQYDVQQDEw5yc3lzbG9nIGNsaWVudDERMA8GA1UECxMIU29tZVVuaXQxEDAO
+BgNVBAoTB1NvbWVPcmcxCzAJBgNVBAgTAkNBMQswCQYDVQQGEwJVUzCCAaIwDQYJ
+KoZIhvcNAQEBBQADggGPADCCAYoCggGBAJ2R2tguPZ2uhcPFp/akZvjIkZG4cCDc
+7egjylP3uFJD86fr+9+KOyywE/pi06FTpFFxH2jZ/bw5SvvJat/ziISwgLzA9RtC
+EfZMGtgsYgtdUGQwmtPbwdV/OVPkvegeBJ3JEuDkVykpAbnx5bx0pudLYeZnXGxO
+7u4iDBsUbegMb+7uw7jd3xXtepZbzIXl41DEziu/tjfmIPxuRX4JvYR6rwcn9Jkj
+Qd822CkxoJaEL/1FLtS0+frcjyPA4AatrQpy2vQ7ocvWpjvsRsSV8nGlrQgf5wYY
+DtuAUZa6JPZkAmvT8HYBNDpyAunL0KpiUQyPg77AR5nSknLtU6VJBdTJofRN3hKd
+GsgXhPOifGdHgkuGHnOG4iYmEJSjmZsImXidPTNdhcJGZZSrcLQ7wSaLEbZmJ4gi
+hAO1CEUyjIEjvmLcb6CqXp8D96f1A3A8eAnQhESMGa9295P8r8b929lMyyB5RHHL
+5lVhqXqvC6Om7empEa/6o12sl+fvK7aoNwIDAQABo4GAMH4wDAYDVR0TAQH/BAIw
+ADAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDwYDVR0PAQH/BAUDAweg
+ADAdBgNVHQ4EFgQUlBeunSFXuHvBrhB7CKkhvKEUAIswHwYDVR0jBBgwFoAUsJ9n
+MyyIiIkfRGJ0nSX/wAYTXdYwDQYJKoZIhvcNAQELBQADggGBAEk9KaiQ6NzNHf7M
+kvPosgCu9Tm1jgRg4qjdMHxtzDxFQZWOtMuDxqqrNEC9FEF5zpEB8Z4VtubIeVK7
+6i6BdSMbI5zlnlxffPD1Gz8AKXe9BNb6UlLvlEC+58D4CJmrxDuKZXaBzy3xh2TP
+Al/s5XkPBuXKc7l0qQdDkt67LfDCrwpGfseOFXNUHDREBOulwX4LJzilVqLMsp03
+qMHK0f4kOxc0oJrH+2+jCgpu1QPoFOLl/6shbRw3qls/f/coWnnS5kd2NOPUf0pe
+j5lBt5ThhnLQIGwJucLa6cHVx+R4BWtTz4/v8hCwWr1cUbNEkxTyBErl0l8KkpCQ
+d0NCuZe2u2AJYEKdNilSiBr33ERZ70peE/ATfk6hv9ysWepeGYJiuybWXMrDtLbw
+X9wzwtdetIvvMxXiNAT5RpsZtFrdBD9ZwCHhJ+xjEycRDQKdnL/H4WbpAfvB9zcJ
+WCJ50FBFjNoHSYrwmhQULOYa8AjVxxrX/27g2mN3P3sDLG6bzw==
+-----END CERTIFICATE-----
diff --git a/tests/testsuites/x.509/client-expired-cert.pem b/tests/testsuites/x.509/client-expired-cert.pem
new file mode 100644
index 0000000..d5fe9a2
--- /dev/null
+++ b/tests/testsuites/x.509/client-expired-cert.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEPTCCAqWgAwIBAgIIXBEoYTa7GecwDQYJKoZIhvcNAQELBQAwRDERMA8GA1UE
+AxMIc29tZU5hbWUxEDAOBgNVBAsTB3JzeXNsb2cxEDAOBgNVBAoTB1NvbWVPcmcx
+CzAJBgNVBAYTAlVTMB4XDTE4MTIxMjE1MjUyMloXDTE4MTIxMzE1MjUyM1owdjEL
+MAkGA1UEAxMCVVMxEDAOBgNVBAsTB1NvbWVPcmgxDzANBgNVBAoTBlNvbWVPVTES
+MBAGA1UEBxMJU29tZXdoZXJlMQswCQYDVQQGEwJDQTEjMCEGCgmSJomT8ixkARkW
+E21hY2hpbmUuZXhhbXBsZS5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQC24qsJF2yax7Ja4xsPQ7lDtkEMx3ni6k0xh7VrzZiRFpegdz1CVerV8bAs
+voTzn1aTWE1lELRO7i4QTAU2sn/kyB34oNuQWd8R1D7J3FJsIE36RM15XmcQ4biX
+H6m9Kx5uEAfdHVSPLgwuQlQM6IshmxV5AS+QrqLK7scZCFpBEb379G4JeJJGdkXR
+p7VYXUo079YSA60TqhWH01dlJdvRmY6sBpYahAOag3f3d7L8eYd9Jv3S6pHxzf/5
+/TqMbYr7m4iPH+cXg/sDNMll66rax9Ei2dk/Za1GKQ1AUvlfto0qKaRg/2FUKhqP
+DGV5uJDbYxlZjD+2s8HSrlSPS70FAgMBAAGjgYAwfjAMBgNVHRMBAf8EAjAAMB0G
+A1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHQ8BAf8EBQMDB6AAMB0G
+A1UdDgQWBBTKFNJvJb22tIrAxnqkVRDvFqukcTAfBgNVHSMEGDAWgBSwn2czLIiI
+iR9EYnSdJf/ABhNd1jANBgkqhkiG9w0BAQsFAAOCAYEAXV+3oTx+/LEL8yHUbRS2
+wQ+kuXuuGJT4nkOFD+m5vNWtM1jGoj1trV/MxC697JlKB4wmBebKvIXcdKTVy2CB
+MqPoKTHSJ4vqfAWYAP9i0nNrxcvi0mHVxlRqPnizPLUkcPCYvnPtnSOCELmWk0mC
+i9K2QUy9e9HulRayaVU8KdPwopy6aJJQyl981T/h/m+q0FcKOIC27nn0VW0ZGHtl
+1PnUTVOP479HNhMg6zmPKxV0Y/WVQDB0Cpok3uuo0V1I9BuQk7Rn6DQqSnNI7/vH
+Ot/5fPEk/SU4OitCH7yV8XnkrPfAhpPrsUrVUd54PQg/KZu9qVTfMAM+j55aDCs7
+HlfrkSB+Jv4YOdlgrSMnstG45WIAYGD32sCPog5F9mJl6BFREcgscQ1BF7Tr/LX2
+d8PaePwRfdHuRDsY4Ydq+F89cP23QNIlxf9r8ODe13v1mfCXpzxksZ8zhxEzPm46
+efGuPdwdb+u6ZRiOqoaAavV9raKCEX5CrvqKeDnZ66WA
+-----END CERTIFICATE-----
diff --git a/tests/testsuites/x.509/client-expired-key.pem b/tests/testsuites/x.509/client-expired-key.pem
new file mode 100644
index 0000000..b53d6f3
--- /dev/null
+++ b/tests/testsuites/x.509/client-expired-key.pem
@@ -0,0 +1,134 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: Medium (2048 bits)
+
+modulus:
+ 00:b6:e2:ab:09:17:6c:9a:c7:b2:5a:e3:1b:0f:43:b9
+ 43:b6:41:0c:c7:79:e2:ea:4d:31:87:b5:6b:cd:98:91
+ 16:97:a0:77:3d:42:55:ea:d5:f1:b0:2c:be:84:f3:9f
+ 56:93:58:4d:65:10:b4:4e:ee:2e:10:4c:05:36:b2:7f
+ e4:c8:1d:f8:a0:db:90:59:df:11:d4:3e:c9:dc:52:6c
+ 20:4d:fa:44:cd:79:5e:67:10:e1:b8:97:1f:a9:bd:2b
+ 1e:6e:10:07:dd:1d:54:8f:2e:0c:2e:42:54:0c:e8:8b
+ 21:9b:15:79:01:2f:90:ae:a2:ca:ee:c7:19:08:5a:41
+ 11:bd:fb:f4:6e:09:78:92:46:76:45:d1:a7:b5:58:5d
+ 4a:34:ef:d6:12:03:ad:13:aa:15:87:d3:57:65:25:db
+ d1:99:8e:ac:06:96:1a:84:03:9a:83:77:f7:77:b2:fc
+ 79:87:7d:26:fd:d2:ea:91:f1:cd:ff:f9:fd:3a:8c:6d
+ 8a:fb:9b:88:8f:1f:e7:17:83:fb:03:34:c9:65:eb:aa
+ da:c7:d1:22:d9:d9:3f:65:ad:46:29:0d:40:52:f9:5f
+ b6:8d:2a:29:a4:60:ff:61:54:2a:1a:8f:0c:65:79:b8
+ 90:db:63:19:59:8c:3f:b6:b3:c1:d2:ae:54:8f:4b:bd
+ 05:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 43:a8:45:67:fe:9f:71:ff:50:af:28:f7:58:c5:50:23
+ 89:a8:35:07:12:c3:6c:b4:94:0f:45:81:95:34:cc:f0
+ 13:b6:0c:86:c0:24:b2:d4:e5:2d:ac:cf:ea:b5:8a:0b
+ e8:44:b1:95:23:01:e1:75:61:db:2b:94:7e:30:b8:f9
+ b5:42:c9:39:11:21:2c:ee:46:55:43:c9:3f:d5:ca:24
+ 85:54:81:e1:95:f5:e3:a1:2e:30:30:d0:48:e6:2f:ae
+ 79:3f:3a:f9:85:21:44:3a:df:cc:b9:43:08:e7:7a:99
+ 3b:1b:4d:81:af:cc:11:9f:2d:fd:f9:ef:fb:d4:0f:df
+ d4:fe:65:70:c9:d2:3c:08:7b:ad:d5:34:af:c6:13:cf
+ 15:b5:82:31:02:52:d2:73:a9:e5:d1:5f:67:c1:a5:72
+ e1:e4:4f:14:c6:fb:70:db:b8:43:ba:25:ea:4a:57:d6
+ 30:ec:e4:c0:8c:24:c5:83:d7:68:9b:96:e1:7c:57:1f
+ 4c:2f:e3:76:9b:bb:b8:e6:86:52:87:fe:d2:a3:b3:bd
+ 30:c0:0e:f6:d2:fe:6d:e9:5b:24:5c:f4:b8:ba:da:d4
+ 47:eb:d5:30:da:3b:1d:03:1f:ad:49:a2:05:34:f0:a1
+ a8:a2:08:e2:ed:ba:03:1c:60:4a:ea:fa:08:4c:88:5d
+
+
+prime1:
+ 00:ca:bc:76:2f:11:58:28:51:bf:a2:a0:23:43:b3:25
+ 1a:56:2c:2e:56:05:24:a7:4b:e0:75:d3:ba:e7:31:20
+ 2b:a2:fc:91:13:6b:b6:5b:c6:21:71:2d:6d:aa:d7:1f
+ b8:d9:86:ea:00:49:19:e7:d0:c1:2e:43:50:83:fd:b9
+ a3:1d:51:c7:ee:45:0b:a9:c0:26:70:da:a6:3b:ea:d8
+ 2f:dc:98:ce:f7:95:84:24:a3:d8:54:57:90:64:63:f3
+ f7:9f:75:02:d8:c7:4e:9f:7d:60:f3:dc:b1:83:bc:42
+ 08:ae:5f:ac:94:b1:74:bf:57:fc:96:0a:44:14:7b:f5
+ d3:
+
+prime2:
+ 00:e6:ef:17:e0:2d:ef:36:07:c3:c2:42:44:d0:fb:e6
+ d6:f5:7d:c4:5d:54:17:e0:ec:1d:6c:84:52:cf:90:a4
+ aa:a5:d0:7c:c6:e6:f0:56:aa:73:27:5c:c1:91:4d:d5
+ 60:7d:9c:a3:96:1a:cb:b1:e7:8e:cb:53:52:2e:35:53
+ 74:46:e9:ff:67:fb:93:5b:94:78:b0:0f:b9:a7:2f:08
+ fe:84:d3:f5:3e:f0:b7:02:a8:41:4e:9c:65:d7:f8:95
+ 7e:82:ef:5f:3c:60:12:2e:6f:3f:a8:df:b3:bf:3b:ed
+ ac:07:ef:0f:d7:35:c7:81:30:a2:18:05:14:72:6c:02
+ c7:
+
+coefficient:
+ 60:35:5f:cb:5b:40:75:b3:57:b8:61:d8:5a:40:c1:91
+ 01:3a:c1:17:35:94:4b:81:06:e9:75:56:8c:97:e3:bb
+ 5a:7d:f5:f1:ac:f8:6f:d0:a2:6c:89:a4:8a:0d:23:78
+ 8a:92:b6:3f:7c:42:00:65:c8:d7:b4:77:19:fd:2f:75
+ e8:99:c4:60:c5:48:f5:74:4d:09:63:a2:b5:cd:01:0e
+ 70:8d:69:03:f0:58:e6:7c:47:93:40:f3:53:9f:d5:97
+ 3a:13:2e:10:aa:17:77:74:67:82:2a:20:5b:fa:96:51
+ cf:58:c8:a4:c4:58:f4:5a:88:42:49:4a:ad:5c:6e:00
+
+
+exp1:
+ 57:8a:b7:91:ad:70:9e:c0:65:fa:88:21:92:1b:2a:1b
+ 4c:38:79:ad:a5:3c:e5:8c:8b:18:f5:db:4f:f7:53:87
+ e4:32:21:46:fc:8c:da:e6:1c:0c:ad:ec:1c:08:16:67
+ 90:6e:84:5e:a9:32:29:7a:67:e0:5d:2a:c8:43:e8:43
+ f9:e6:15:69:da:a0:a5:a5:16:34:47:05:de:fb:92:6c
+ 60:5a:0f:8c:b3:20:43:5e:08:8c:aa:de:eb:aa:89:6f
+ 54:88:87:39:2a:1e:d6:19:a2:a2:ca:9a:50:63:1b:34
+ 7a:6f:4f:ab:49:51:3b:4a:78:04:25:dc:ad:e7:b5:07
+
+
+exp2:
+ 19:ee:59:10:fc:37:73:2a:b6:09:97:25:61:0e:18:22
+ a5:18:45:37:71:9c:e8:cd:ba:94:17:db:b0:a0:fe:4c
+ 87:27:fd:0a:dc:9d:ba:2d:93:96:a4:ec:bb:63:31:05
+ 8f:b5:4a:0d:2d:df:17:8f:f7:d1:ce:fe:58:5f:f6:8a
+ 04:f8:7b:8c:72:8c:5e:69:32:90:1a:83:ef:48:f1:ca
+ 9a:a1:ae:55:2d:f4:6e:e0:f3:cc:5e:f5:74:a5:de:2b
+ 81:8a:5d:78:4b:15:5f:8f:70:67:87:0f:08:f7:32:bd
+ f1:7a:1f:9e:3b:d4:b6:25:fe:dd:91:9c:75:28:b9:bb
+
+
+
+Public Key PIN:
+ pin-sha256:ixzIAak4pRfFjtaG95FtWd+Iu8vB5m6nknYP5EGaAqg=
+Public Key ID:
+ sha256:8b1cc801a938a517c58ed686f7916d59df88bbcbc1e66ea792760fe4419a02a8
+ sha1:ca14d26f25bdb6b48ac0c67aa45510ef16aba471
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAtuKrCRdsmseyWuMbD0O5Q7ZBDMd54upNMYe1a82YkRaXoHc9
+QlXq1fGwLL6E859Wk1hNZRC0Tu4uEEwFNrJ/5Mgd+KDbkFnfEdQ+ydxSbCBN+kTN
+eV5nEOG4lx+pvSsebhAH3R1Ujy4MLkJUDOiLIZsVeQEvkK6iyu7HGQhaQRG9+/Ru
+CXiSRnZF0ae1WF1KNO/WEgOtE6oVh9NXZSXb0ZmOrAaWGoQDmoN393ey/HmHfSb9
+0uqR8c3/+f06jG2K+5uIjx/nF4P7AzTJZeuq2sfRItnZP2WtRikNQFL5X7aNKimk
+YP9hVCoajwxlebiQ22MZWYw/trPB0q5Uj0u9BQIDAQABAoIBAEOoRWf+n3H/UK8o
+91jFUCOJqDUHEsNstJQPRYGVNMzwE7YMhsAkstTlLazP6rWKC+hEsZUjAeF1Ydsr
+lH4wuPm1Qsk5ESEs7kZVQ8k/1cokhVSB4ZX146EuMDDQSOYvrnk/OvmFIUQ638y5
+Qwjnepk7G02Br8wRny39+e/71A/f1P5lcMnSPAh7rdU0r8YTzxW1gjECUtJzqeXR
+X2fBpXLh5E8Uxvtw27hDuiXqSlfWMOzkwIwkxYPXaJuW4XxXH0wv43abu7jmhlKH
+/tKjs70wwA720v5t6VskXPS4utrUR+vVMNo7HQMfrUmiBTTwoaiiCOLtugMcYErq
++ghMiF0CgYEAyrx2LxFYKFG/oqAjQ7MlGlYsLlYFJKdL4HXTuucxICui/JETa7Zb
+xiFxLW2q1x+42YbqAEkZ59DBLkNQg/25ox1Rx+5FC6nAJnDapjvq2C/cmM73lYQk
+o9hUV5BkY/P3n3UC2MdOn31g89yxg7xCCK5frJSxdL9X/JYKRBR79dMCgYEA5u8X
+4C3vNgfDwkJE0Pvm1vV9xF1UF+DsHWyEUs+QpKql0HzG5vBWqnMnXMGRTdVgfZyj
+lhrLseeOy1NSLjVTdEbp/2f7k1uUeLAPuacvCP6E0/U+8LcCqEFOnGXX+JV+gu9f
+PGASLm8/qN+zvzvtrAfvD9c1x4EwohgFFHJsAscCgYBXireRrXCewGX6iCGSGyob
+TDh5raU85YyLGPXbT/dTh+QyIUb8jNrmHAyt7BwIFmeQboReqTIpemfgXSrIQ+hD
++eYVadqgpaUWNEcF3vuSbGBaD4yzIENeCIyq3uuqiW9UiIc5Kh7WGaKiyppQYxs0
+em9Pq0lRO0p4BCXcree1BwKBgBnuWRD8N3MqtgmXJWEOGCKlGEU3cZzozbqUF9uw
+oP5Mhyf9Ctydui2TlqTsu2MxBY+1Sg0t3xeP99HO/lhf9ooE+HuMcoxeaTKQGoPv
+SPHKmqGuVS30buDzzF71dKXeK4GKXXhLFV+PcGeHDwj3Mr3xeh+eO9S2Jf7dkZx1
+KLm7AoGAYDVfy1tAdbNXuGHYWkDBkQE6wRc1lEuBBul1VoyX47taffXxrPhv0KJs
+iaSKDSN4ipK2P3xCAGXI17R3Gf0vdeiZxGDFSPV0TQljorXNAQ5wjWkD8FjmfEeT
+QPNTn9WXOhMuEKoXd3RngiogW/qWUc9YyKTEWPRaiEJJSq1cbgA=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/testsuites/x.509/client-key.pem b/tests/testsuites/x.509/client-key.pem
new file mode 100644
index 0000000..596fa27
--- /dev/null
+++ b/tests/testsuites/x.509/client-key.pem
@@ -0,0 +1,182 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:9d:91:da:d8:2e:3d:9d:ae:85:c3:c5:a7:f6:a4:66
+ f8:c8:91:91:b8:70:20:dc:ed:e8:23:ca:53:f7:b8:52
+ 43:f3:a7:eb:fb:df:8a:3b:2c:b0:13:fa:62:d3:a1:53
+ a4:51:71:1f:68:d9:fd:bc:39:4a:fb:c9:6a:df:f3:88
+ 84:b0:80:bc:c0:f5:1b:42:11:f6:4c:1a:d8:2c:62:0b
+ 5d:50:64:30:9a:d3:db:c1:d5:7f:39:53:e4:bd:e8:1e
+ 04:9d:c9:12:e0:e4:57:29:29:01:b9:f1:e5:bc:74:a6
+ e7:4b:61:e6:67:5c:6c:4e:ee:ee:22:0c:1b:14:6d:e8
+ 0c:6f:ee:ee:c3:b8:dd:df:15:ed:7a:96:5b:cc:85:e5
+ e3:50:c4:ce:2b:bf:b6:37:e6:20:fc:6e:45:7e:09:bd
+ 84:7a:af:07:27:f4:99:23:41:df:36:d8:29:31:a0:96
+ 84:2f:fd:45:2e:d4:b4:f9:fa:dc:8f:23:c0:e0:06:ad
+ ad:0a:72:da:f4:3b:a1:cb:d6:a6:3b:ec:46:c4:95:f2
+ 71:a5:ad:08:1f:e7:06:18:0e:db:80:51:96:ba:24:f6
+ 64:02:6b:d3:f0:76:01:34:3a:72:02:e9:cb:d0:aa:62
+ 51:0c:8f:83:be:c0:47:99:d2:92:72:ed:53:a5:49:05
+ d4:c9:a1:f4:4d:de:12:9d:1a:c8:17:84:f3:a2:7c:67
+ 47:82:4b:86:1e:73:86:e2:26:26:10:94:a3:99:9b:08
+ 99:78:9d:3d:33:5d:85:c2:46:65:94:ab:70:b4:3b:c1
+ 26:8b:11:b6:66:27:88:22:84:03:b5:08:45:32:8c:81
+ 23:be:62:dc:6f:a0:aa:5e:9f:03:f7:a7:f5:03:70:3c
+ 78:09:d0:84:44:8c:19:af:76:f7:93:fc:af:c6:fd:db
+ d9:4c:cb:20:79:44:71:cb:e6:55:61:a9:7a:af:0b:a3
+ a6:ed:e9:a9:11:af:fa:a3:5d:ac:97:e7:ef:2b:b6:a8
+ 37:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 60:cd:c5:dc:80:74:1c:56:a7:19:82:6a:51:6d:e9:51
+ 38:af:ae:0d:d8:dd:67:bd:c5:9b:8f:67:0c:ce:b1:c3
+ cb:82:c3:c9:27:29:9e:77:32:e9:e3:2f:2a:03:78:06
+ 80:7e:76:24:8d:a0:84:2d:d2:b2:63:a9:04:53:72:f0
+ ca:1b:1d:5b:92:7a:1f:9a:37:6d:c4:24:41:08:2f:21
+ 32:0d:8b:8a:e3:53:a4:7f:0c:bd:64:9c:28:4b:dd:7d
+ 4a:8e:c8:c9:5f:9f:68:cb:27:a3:5c:48:9f:02:2f:b3
+ f3:ac:fe:c7:4b:91:c2:e0:a9:6e:43:6f:b3:9a:5e:30
+ 9d:e7:f5:ca:4a:de:0c:7b:45:3d:c5:f8:39:eb:9d:33
+ 8d:60:8b:a5:77:0f:74:c2:2e:4b:c7:57:6c:3a:81:b3
+ 4d:48:10:a6:6c:70:54:a7:d8:81:b2:45:84:96:bb:42
+ 14:d5:8d:d6:5a:99:a0:e6:8c:f0:67:af:cc:32:6e:29
+ e5:4d:73:ec:4b:14:2e:a6:91:27:9e:d4:45:62:52:33
+ 66:94:c8:29:29:4d:bd:62:7b:f7:67:ed:26:02:33:f4
+ 70:79:43:ff:ec:0f:92:80:b2:a4:f0:a2:91:00:f9:0e
+ 51:22:53:f5:51:e2:97:e8:18:be:36:34:d2:c8:cd:0e
+ 3c:66:8e:2c:a8:4f:46:66:5e:01:4f:1e:03:6e:e0:63
+ d4:15:f5:28:59:e4:e0:47:df:57:20:d0:39:09:d8:65
+ 1c:3d:c9:2f:69:77:5c:4c:4f:90:ea:07:fc:51:0c:2b
+ 0c:f9:85:06:f8:08:04:37:86:45:ee:58:c9:4c:2b:ba
+ 00:bf:c2:a0:92:f7:c2:31:82:43:52:0f:63:4d:96:82
+ 1c:60:70:63:ac:72:db:ea:b8:4a:b3:a7:15:7a:c4:71
+ 4a:dd:7e:8b:40:b7:b1:78:7f:14:60:d1:89:cf:6a:41
+ 58:b5:cf:80:58:63:ad:fe:1f:15:bb:b2:10:db:07:41
+
+
+prime1:
+ 00:d0:04:9a:29:56:25:fd:9b:53:c0:a0:2f:ee:a8:49
+ b0:a3:f4:33:a7:f3:29:5f:63:2c:05:5e:75:16:b4:62
+ 2a:64:ea:e0:a6:64:aa:ce:aa:49:9d:10:1b:e5:56:c5
+ 60:a9:54:87:3b:f7:55:49:c0:58:65:fd:32:73:b3:e7
+ 79:ad:d4:49:27:b3:bd:0f:00:11:60:6a:c1:98:3b:71
+ c7:83:7c:59:a6:61:c5:29:da:4d:8a:e5:be:a7:76:71
+ ce:0d:2d:99:07:80:ac:df:42:29:6d:19:93:f2:5f:6d
+ 27:6d:31:db:2c:6a:38:ab:3e:39:db:5d:d6:b8:b7:34
+ eb:0b:9c:a7:7f:9d:52:75:4a:53:25:de:df:0f:64:18
+ 01:8b:b5:20:c3:7d:52:b3:1f:b8:95:0f:18:b3:ca:50
+ 5e:89:b7:ae:61:40:24:74:84:29:e1:9d:34:94:aa:f1
+ f2:d4:d8:ce:73:cd:ee:c1:c7:80:f1:75:60:2f:c8:6e
+ 21:
+
+prime2:
+ 00:c1:ea:4c:cf:a8:a0:55:cb:e0:82:81:ec:ba:f7:41
+ a0:33:27:e2:42:85:8f:94:51:c5:a2:07:23:19:ea:87
+ 87:af:4e:fc:11:9c:e8:d0:e6:83:8d:1d:e5:09:b3:e0
+ 30:13:92:23:37:27:bc:2c:90:09:e0:ff:31:27:1e:8a
+ 0c:fe:ca:d2:a1:d2:a4:74:ae:21:db:f7:63:7f:38:44
+ b9:97:59:9f:31:bf:55:80:97:fe:72:e6:6c:b0:1b:35
+ 3c:18:76:5a:53:75:16:da:f1:97:f7:29:39:e5:70:df
+ 1c:fc:91:0b:e8:3a:20:d3:b4:61:3a:c8:81:f2:6c:49
+ 1f:ba:07:cb:a8:0c:17:15:0f:8f:be:c7:5e:f3:0e:42
+ cb:1a:11:ec:3e:25:25:fc:ce:c0:dd:99:49:c7:10:1a
+ d1:7c:5f:ca:d2:f3:d2:6f:ad:4b:7b:92:8a:55:ce:dc
+ b7:dc:b8:1e:1e:e5:d7:93:85:9e:a0:58:53:6e:03:db
+ 57:
+
+coefficient:
+ 00:ce:59:bc:fc:f2:13:ba:d7:78:e2:d3:ec:10:28:ff
+ 9c:af:d1:8d:a0:d8:f3:ed:62:8d:15:b0:69:80:e8:ba
+ 8f:bc:34:ce:36:35:a1:16:18:f2:46:0f:64:a4:d6:3b
+ 5a:0c:0c:a0:2e:bf:c6:f2:75:1d:83:93:be:5c:14:8c
+ 02:32:84:7e:24:ea:7b:d3:52:74:1c:63:75:00:c1:04
+ 44:bf:76:e3:67:34:ce:fe:e5:c3:7c:f1:59:c3:48:4b
+ 2f:b2:24:60:0c:7e:e1:f7:b1:af:f5:07:ed:81:08:ac
+ 4c:e0:d3:98:c3:fb:20:24:5d:88:6c:2e:dd:4b:b9:9d
+ ef:56:76:42:83:22:95:e2:23:e4:5a:b5:08:f7:02:e5
+ b5:69:99:da:be:5f:1a:24:49:b4:5d:37:22:39:f6:23
+ ed:66:40:de:50:9e:f4:6d:38:41:75:46:14:a3:35:51
+ 2e:5e:84:db:1d:94:8c:df:47:83:02:cf:ec:21:4a:d5
+ 48:
+
+exp1:
+ 00:c3:aa:f0:8f:dd:77:12:dc:9e:a5:5c:88:79:c7:56
+ b9:8f:1f:4f:cf:b5:4c:bf:6a:fb:a7:79:38:4e:49:12
+ e5:a9:d3:bd:c9:06:7c:1c:b5:d5:54:a6:28:77:4b:6d
+ 92:04:f5:7b:d7:8e:49:6d:7c:3e:2a:81:46:89:cb:39
+ fb:1c:e5:c8:82:4d:f1:92:40:90:17:cf:93:96:ec:a3
+ 93:f6:3c:6b:df:b3:ab:d0:38:86:24:17:03:85:66:46
+ 9a:79:8e:e0:99:4c:12:50:57:5d:bc:40:09:08:3d:76
+ e1:55:37:46:60:ba:f1:df:32:43:1d:f3:60:dc:93:88
+ 75:67:90:cd:85:9e:a8:47:a7:c8:1a:a1:4f:d4:9c:64
+ 70:5f:c7:da:af:c8:1c:98:5d:48:34:fd:e4:50:8a:07
+ 9b:45:93:bf:b5:be:ae:0b:e3:9d:b9:99:34:32:7b:b1
+ e6:a7:0b:e0:f6:d1:48:ba:82:3c:e9:e3:6c:bc:c5:9d
+ c1:
+
+exp2:
+ 00:a4:7e:05:24:4e:0d:9c:59:f2:9b:a2:6c:d6:f8:b1
+ 41:9c:c3:63:6a:3c:73:dc:44:35:5a:c9:a5:1b:f1:d7
+ 7f:e0:d5:26:7c:26:57:54:05:86:68:29:88:c5:5f:41
+ 78:66:d1:9b:6f:c9:14:15:d5:25:9c:27:bd:61:4a:c5
+ 9e:5a:70:60:96:86:e1:9c:5c:ae:3a:32:b3:c3:12:4f
+ 32:03:d2:31:79:78:ad:a6:04:c9:02:5c:b6:ab:f8:98
+ 82:de:d9:5e:ab:d6:f2:49:4d:91:34:47:53:66:6f:05
+ c4:47:f7:1e:5b:a3:1b:7f:9a:4e:b4:17:ac:2b:a1:71
+ b2:29:13:3d:cd:d2:5b:ae:30:e2:25:da:67:8f:d4:74
+ 12:67:8d:f6:91:8c:df:99:81:25:17:95:55:81:38:07
+ 17:d6:e2:47:62:05:14:68:49:5f:73:76:8e:44:55:d2
+ e3:60:a7:0a:5d:f9:68:92:2a:51:b2:00:da:dc:c3:06
+ c7:
+
+
+Public Key PIN:
+ pin-sha256:aKORpr08YK1r+ZlFwE2Jr4IWb89uVOwdRatfTSZzcZ8=
+Public Key ID:
+ sha256:68a391a6bd3c60ad6bf99945c04d89af82166fcf6e54ec1d45ab5f4d2673719f
+ sha1:9417ae9d2157b87bc1ae107b08a921bca114008b
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIG5QIBAAKCAYEAnZHa2C49na6Fw8Wn9qRm+MiRkbhwINzt6CPKU/e4UkPzp+v7
+34o7LLAT+mLToVOkUXEfaNn9vDlK+8lq3/OIhLCAvMD1G0IR9kwa2CxiC11QZDCa
+09vB1X85U+S96B4EnckS4ORXKSkBufHlvHSm50th5mdcbE7u7iIMGxRt6Axv7u7D
+uN3fFe16llvMheXjUMTOK7+2N+Yg/G5Ffgm9hHqvByf0mSNB3zbYKTGgloQv/UUu
+1LT5+tyPI8DgBq2tCnLa9Duhy9amO+xGxJXycaWtCB/nBhgO24BRlrok9mQCa9Pw
+dgE0OnIC6cvQqmJRDI+DvsBHmdKScu1TpUkF1Mmh9E3eEp0ayBeE86J8Z0eCS4Ye
+c4biJiYQlKOZmwiZeJ09M12FwkZllKtwtDvBJosRtmYniCKEA7UIRTKMgSO+Ytxv
+oKpenwP3p/UDcDx4CdCERIwZr3b3k/yvxv3b2UzLIHlEccvmVWGpeq8Lo6bt6akR
+r/qjXayX5+8rtqg3AgMBAAECggGAYM3F3IB0HFanGYJqUW3pUTivrg3Y3We9xZuP
+ZwzOscPLgsPJJymedzLp4y8qA3gGgH52JI2ghC3SsmOpBFNy8MobHVuSeh+aN23E
+JEEILyEyDYuK41Okfwy9ZJwoS919So7IyV+faMsno1xInwIvs/Os/sdLkcLgqW5D
+b7OaXjCd5/XKSt4Me0U9xfg5650zjWCLpXcPdMIuS8dXbDqBs01IEKZscFSn2IGy
+RYSWu0IU1Y3WWpmg5ozwZ6/MMm4p5U1z7EsULqaRJ57URWJSM2aUyCkpTb1ie/dn
+7SYCM/RweUP/7A+SgLKk8KKRAPkOUSJT9VHil+gYvjY00sjNDjxmjiyoT0ZmXgFP
+HgNu4GPUFfUoWeTgR99XINA5CdhlHD3JL2l3XExPkOoH/FEMKwz5hQb4CAQ3hkXu
+WMlMK7oAv8KgkvfCMYJDUg9jTZaCHGBwY6xy2+q4SrOnFXrEcUrdfotAt7F4fxRg
+0YnPakFYtc+AWGOt/h8Vu7IQ2wdBAoHBANAEmilWJf2bU8CgL+6oSbCj9DOn8ylf
+YywFXnUWtGIqZOrgpmSqzqpJnRAb5VbFYKlUhzv3VUnAWGX9MnOz53mt1Ekns70P
+ABFgasGYO3HHg3xZpmHFKdpNiuW+p3Zxzg0tmQeArN9CKW0Zk/JfbSdtMdssajir
+PjnbXda4tzTrC5ynf51SdUpTJd7fD2QYAYu1IMN9UrMfuJUPGLPKUF6Jt65hQCR0
+hCnhnTSUqvHy1NjOc83uwceA8XVgL8huIQKBwQDB6kzPqKBVy+CCgey690GgMyfi
+QoWPlFHFogcjGeqHh69O/BGc6NDmg40d5Qmz4DATkiM3J7wskAng/zEnHooM/srS
+odKkdK4h2/djfzhEuZdZnzG/VYCX/nLmbLAbNTwYdlpTdRba8Zf3KTnlcN8c/JEL
+6Dog07RhOsiB8mxJH7oHy6gMFxUPj77HXvMOQssaEew+JSX8zsDdmUnHEBrRfF/K
+0vPSb61Le5KKVc7ct9y4Hh7l15OFnqBYU24D21cCgcEAw6rwj913EtyepVyIecdW
+uY8fT8+1TL9q+6d5OE5JEuWp073JBnwctdVUpih3S22SBPV7145JbXw+KoFGics5
++xzlyIJN8ZJAkBfPk5bso5P2PGvfs6vQOIYkFwOFZkaaeY7gmUwSUFddvEAJCD12
+4VU3RmC68d8yQx3zYNyTiHVnkM2FnqhHp8gaoU/UnGRwX8far8gcmF1INP3kUIoH
+m0WTv7W+rgvjnbmZNDJ7seanC+D20Ui6gjzp42y8xZ3BAoHBAKR+BSRODZxZ8pui
+bNb4sUGcw2NqPHPcRDVayaUb8dd/4NUmfCZXVAWGaCmIxV9BeGbRm2/JFBXVJZwn
+vWFKxZ5acGCWhuGcXK46MrPDEk8yA9IxeXitpgTJAly2q/iYgt7ZXqvW8klNkTRH
+U2ZvBcRH9x5boxt/mk60F6wroXGyKRM9zdJbrjDiJdpnj9R0EmeN9pGM35mBJReV
+VYE4BxfW4kdiBRRoSV9zdo5EVdLjYKcKXflokipRsgDa3MMGxwKBwQDOWbz88hO6
+13ji0+wQKP+cr9GNoNjz7WKNFbBpgOi6j7w0zjY1oRYY8kYPZKTWO1oMDKAuv8by
+dR2Dk75cFIwCMoR+JOp701J0HGN1AMEERL9242c0zv7lw3zxWcNISy+yJGAMfuH3
+sa/1B+2BCKxM4NOYw/sgJF2IbC7dS7md71Z2QoMileIj5Fq1CPcC5bVpmdq+Xxok
+SbRdNyI59iPtZkDeUJ70bThBdUYUozVRLl6E2x2UjN9HgwLP7CFK1Ug=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/testsuites/x.509/client-new.csr b/tests/testsuites/x.509/client-new.csr
new file mode 100644
index 0000000..e7aeecf
--- /dev/null
+++ b/tests/testsuites/x.509/client-new.csr
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIID0DCCAjgCAQAwgYoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTERMA8GA1UE
+BwwIU29tZUNpdHkxETAPBgNVBAoMCFNvbWVDb21wMREwDwYDVQQLDAhTb21lVW5p
+dDEQMA4GA1UEAwwHcnN5c2xvZzEjMCEGCSqGSIb3DQEJARYUYWxvcmJhY2hAYWRp
+c2Nvbi5jb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCdkdrYLj2d
+roXDxaf2pGb4yJGRuHAg3O3oI8pT97hSQ/On6/vfijsssBP6YtOhU6RRcR9o2f28
+OUr7yWrf84iEsIC8wPUbQhH2TBrYLGILXVBkMJrT28HVfzlT5L3oHgSdyRLg5Fcp
+KQG58eW8dKbnS2HmZ1xsTu7uIgwbFG3oDG/u7sO43d8V7XqWW8yF5eNQxM4rv7Y3
+5iD8bkV+Cb2Eeq8HJ/SZI0HfNtgpMaCWhC/9RS7UtPn63I8jwOAGra0Kctr0O6HL
+1qY77EbElfJxpa0IH+cGGA7bgFGWuiT2ZAJr0/B2ATQ6cgLpy9CqYlEMj4O+wEeZ
+0pJy7VOlSQXUyaH0Td4SnRrIF4TzonxnR4JLhh5zhuImJhCUo5mbCJl4nT0zXYXC
+RmWUq3C0O8EmixG2ZieIIoQDtQhFMoyBI75i3G+gql6fA/en9QNwPHgJ0IREjBmv
+dveT/K/G/dvZTMsgeURxy+ZVYal6rwujpu3pqRGv+qNdrJfn7yu2qDcCAwEAAaAA
+MA0GCSqGSIb3DQEBCwUAA4IBgQBhQ5VEn10CTlB6GSLwyHPfq5jAYaH+lUcIrN4C
+cOPCGs/GDB6erAED/KYlKOseD/KYNH5PguecuVnS7ZndfzN+nlukd8dE6qTe/fTG
+6zjPDhh7HuoVtjdh6tDqMUteBA8p7I3kSf/fmK2JYVp3nszYek8/RQoeBI7UZxEE
+Y2X2GvwOJK0FdqJUJS288rRh+aqGNJ23CFGUV36YJ/oBIS+0FQjyPIM9uEI/O1lf
+VLqlJ3uWKeb875QXey5IvgG7S37Wkf1IVEWxLXxv90Py515TsBeC4R8ttmo9jEUV
+l+ihbs+fxgCN6YD4/saVeXhso59IZFy/rVjq6vDYX4PW/T4kZMHjP+Zq/zRXul1S
+Ft0u25Pn4ffCtFuQ+lxLk5NID/uhSGznjFV/l4Q+uvQinNbFyoB/3VNQC1PvkSsg
+90BTYQSyn59un1R6wt4dkR51B+Hxk7uMlQIL/xY4PYTJrUBBk+ovbQG1wZGmla+X
+tZ1y+qWCh7Dh7NE6qulhdijgydE=
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/testsuites/x.509/client-revoked-key.pem b/tests/testsuites/x.509/client-revoked-key.pem
new file mode 100644
index 0000000..8806a6e
--- /dev/null
+++ b/tests/testsuites/x.509/client-revoked-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC//hRd6ZxsZxU8
+1EmdWyrqQ8K8ntA6XlUvaAArC9rcz/fZpxugozHdqAcTntw2dbg06hca9h3bMx5F
+NoCunJOmAk4m+AfeHM6e508l11kkSV40RFSHq+BtWiRBGb8zw6UR1lDA920tEgPM
+C7nqsoVdka2Ezr6bC8LrAZe4OtwcuNJD6JZe8ITimBh7FcavDLuOmJYhe81vDZ+E
+Wb+RqLpqybxfSvMSTTPn3LA46XHY79D9nh/QWrupOpHYHqee+qwTW6Ot6IcL9LX4
+qA2nsVlAJkJ6BeQxZvgF0f2XX66TCtlFbKPfMu4ReIMvujYXdpiD1gj7MQ6BfVeA
+EDzeDUsNAgMBAAECggEAQWSXJ02Ue8+4ihl8YV5WBajCwWAOaHMM7LKtq/vDtgYX
+00h5voMXTvoWPvaS5vG9pjg9Wm+Nx8VngAeKWO7300lhuSAt/dcuAS2j5a2trRBY
+R9EmQXenX1eelZXhbA4tQSAQLUmZJArIxE0SLABWMIKX6W5JuaGN6GGIfbV+l0E9
+RjQoj+k/XmlrUm11/KcRoL83JqL6wNuxi+AiHnFYEpaxdi/+U9RpVegiRzfS4OH7
+COOm+WEbjJSqyON4BRLGwEJaTcyFOozumyCRNnQIJJx7XW1m5RV+eowDdLcfbdma
+dqGDlPqKSwcr8kZhqXlmnOIgiuxUwGI6WhOjAMAOuQKBgQDe9QPX48Fvw5Yaenp4
+kvEU3lzb6JPYz07ECZ3yz7mfSbJmArj/nDqSiX1UdYInD2dMYw4gPdTX9iIMExXk
+dRTo72ipuNzC3w97GkLDHMKNlCnPrSIFWrh0JqQBI+uQOTXqp0kU25SMzp1AtDlW
+UhtXnt+FdKQDYwXyuFrYkfTnSwKBgQDcckTXY9YSfL4IauNG1mPsJM/+UvAmrKdp
+PDAi7ODVT0zq6h7kn30RUg+4Ebtyag9APdH9W8ta4kZVxID2/r5tY9bHxPAGD6Yd
+8cl0Bii6Rzd3NI5+xddqtZyz/A9PCPeKW3v0mLU16kemGq651bLHtwL5o6AEHXIn
+1T3U6d3oBwKBgQCfJU2FAPHGkVnHtL1O67RiLQcjgbRnAjM7A5JXC6d35+cLoc3j
+xuSYTMPFUcuBjiEyCVK/+OLA9NQAwm7SEDDIxHt1CpuqDgbC3E/jbdgBr0zZDMBI
+CiW34w0WM0mmPPAbeyVTWhmDGMhuszZqQ1l5BdKPNF8Oe9R3GNjf1e92WQKBgQCd
+I2cnEid6rijX3zl7OT+pCOSqqXw+VTxQq3K0sp3h79EocxLqbTW9rv09fIZdnHSa
+mnahX1mpwznX0WcMqbIcT9q+NAfUijsjhULQzcMiZbmH45Lfky9nBWZadgaDlCTA
+H05QoLorYIEKSmLaXRY/fplEUfqydDr3Ye3dY4em6QKBgQC0Heucqyw9THbnmHsr
+wIIb/L0eagI8BReJ+CWRAuhid0BmsRtIZf6mmdQl+vwrt4+O8PtCyJoeiI3qrht6
+SL65po9ERpSijV5lL6TS7VI22xNPtzd1Xf/ACg6/An/qSJeqYKn1DEqznSai8zXx
+PLz21hIcNxaxmTG34HMq+h4BGw==
+-----END PRIVATE KEY-----
diff --git a/tests/testsuites/x.509/client-revoked-valid.pem b/tests/testsuites/x.509/client-revoked-valid.pem
new file mode 100644
index 0000000..8bc2b8a
--- /dev/null
+++ b/tests/testsuites/x.509/client-revoked-valid.pem
@@ -0,0 +1,92 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 3 (0x3)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=someName, OU=rsyslog, O=SomeOrg, C=US
+ Validity
+ Not Before: Jul 6 13:38:06 2023 GMT
+ Not After : Jun 12 13:38:06 2123 GMT
+ Subject: C=DE, ST=NRW, O=Adiscon GmbH, OU=rsyslog, CN=rsyslog revoked certificate test/emailAddress=alorbach@adiscon.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:bf:fe:14:5d:e9:9c:6c:67:15:3c:d4:49:9d:5b:
+ 2a:ea:43:c2:bc:9e:d0:3a:5e:55:2f:68:00:2b:0b:
+ da:dc:cf:f7:d9:a7:1b:a0:a3:31:dd:a8:07:13:9e:
+ dc:36:75:b8:34:ea:17:1a:f6:1d:db:33:1e:45:36:
+ 80:ae:9c:93:a6:02:4e:26:f8:07:de:1c:ce:9e:e7:
+ 4f:25:d7:59:24:49:5e:34:44:54:87:ab:e0:6d:5a:
+ 24:41:19:bf:33:c3:a5:11:d6:50:c0:f7:6d:2d:12:
+ 03:cc:0b:b9:ea:b2:85:5d:91:ad:84:ce:be:9b:0b:
+ c2:eb:01:97:b8:3a:dc:1c:b8:d2:43:e8:96:5e:f0:
+ 84:e2:98:18:7b:15:c6:af:0c:bb:8e:98:96:21:7b:
+ cd:6f:0d:9f:84:59:bf:91:a8:ba:6a:c9:bc:5f:4a:
+ f3:12:4d:33:e7:dc:b0:38:e9:71:d8:ef:d0:fd:9e:
+ 1f:d0:5a:bb:a9:3a:91:d8:1e:a7:9e:fa:ac:13:5b:
+ a3:ad:e8:87:0b:f4:b5:f8:a8:0d:a7:b1:59:40:26:
+ 42:7a:05:e4:31:66:f8:05:d1:fd:97:5f:ae:93:0a:
+ d9:45:6c:a3:df:32:ee:11:78:83:2f:ba:36:17:76:
+ 98:83:d6:08:fb:31:0e:81:7d:57:80:10:3c:de:0d:
+ 4b:0d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 20:CE:A2:54:99:CF:22:9A:5C:BB:D4:1E:B0:1E:43:73:63:72:AA:DE
+ X509v3 Authority Key Identifier:
+ keyid:B0:9F:67:33:2C:88:88:89:1F:44:62:74:9D:25:FF:C0:06:13:5D:D6
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 65:ac:7c:30:d0:01:ce:d7:ff:28:61:6c:8d:99:15:ce:45:22:
+ 8a:39:70:a4:a6:ce:48:94:e3:4b:8c:be:55:c4:66:96:49:49:
+ 4b:e0:4c:95:fd:73:02:54:3a:df:34:2f:96:16:48:ec:c2:23:
+ 3d:ee:b4:5a:dd:a0:c9:eb:85:f4:fd:e8:d5:8f:f3:dc:ce:4a:
+ 88:bb:be:19:81:3f:8b:0f:09:23:46:14:c9:f5:35:5a:cf:25:
+ 7c:92:df:b9:90:5d:ff:4f:21:40:9c:24:7c:0f:1f:3f:62:d1:
+ 7b:cc:40:7d:c6:61:49:f3:84:26:78:ed:87:70:06:9c:93:05:
+ a5:c4:7e:60:3d:d0:4a:2c:e4:d6:e5:33:f8:07:dd:5a:0e:9a:
+ 93:17:50:29:1a:ff:66:61:d9:40:a7:fb:cc:7b:62:b7:9d:29:
+ 1a:2a:3d:7b:93:87:eb:52:4e:00:19:19:3c:4d:73:fc:3d:ed:
+ eb:9d:92:30:bc:b0:ed:51:15:ce:b7:3c:00:09:0c:9d:6d:8b:
+ 2b:c9:f5:66:d4:49:44:58:3d:e7:61:3d:6b:21:05:ff:1d:55:
+ 59:dd:e4:a6:2f:e5:96:82:eb:24:33:2e:47:61:a5:f8:4d:ab:
+ ad:fc:64:f8:8b:9e:0e:62:8c:16:1d:79:18:74:18:9c:a2:19:
+ c3:24:0d:6e:45:63:f9:08:92:7d:44:0b:96:c7:48:84:72:97:
+ 22:23:bf:10:0a:d7:4e:43:8a:db:60:cd:5d:80:5e:71:fa:c2:
+ b6:68:10:ee:cc:29:86:15:d3:d9:93:2a:cc:73:88:be:9f:ad:
+ d0:c5:9c:a4:e4:86:38:e7:41:84:3a:d0:f3:67:1f:2c:40:d7:
+ 04:b1:ea:32:13:49:a5:82:1a:a5:6c:3f:5f:dc:fd:55:14:03:
+ 8b:d7:bd:01:9e:bc:c5:e4:a1:a8:a8:9d:bc:cd:1f:5b:fc:df:
+ 59:b7:0d:aa:47:a0:08:cd:6e:f7:c8:9d:d3:dd:4e:8b:aa:cc:
+ 54:20:a0:2b:63:96
+-----BEGIN CERTIFICATE-----
+MIIEUTCCArmgAwIBAgIBAzANBgkqhkiG9w0BAQsFADBEMREwDwYDVQQDEwhzb21l
+TmFtZTEQMA4GA1UECxMHcnN5c2xvZzEQMA4GA1UEChMHU29tZU9yZzELMAkGA1UE
+BhMCVVMwIBcNMjMwNzA2MTMzODA2WhgPMjEyMzA2MTIxMzM4MDZaMIGUMQswCQYD
+VQQGEwJERTEMMAoGA1UECAwDTlJXMRUwEwYDVQQKDAxBZGlzY29uIEdtYkgxEDAO
+BgNVBAsMB3JzeXNsb2cxKTAnBgNVBAMMIHJzeXNsb2cgcmV2b2tlZCBjZXJ0aWZp
+Y2F0ZSB0ZXN0MSMwIQYJKoZIhvcNAQkBFhRhbG9yYmFjaEBhZGlzY29uLmNvbTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/+FF3pnGxnFTzUSZ1bKupD
+wrye0DpeVS9oACsL2tzP99mnG6CjMd2oBxOe3DZ1uDTqFxr2HdszHkU2gK6ck6YC
+Tib4B94czp7nTyXXWSRJXjREVIer4G1aJEEZvzPDpRHWUMD3bS0SA8wLueqyhV2R
+rYTOvpsLwusBl7g63By40kPoll7whOKYGHsVxq8Mu46YliF7zW8Nn4RZv5GoumrJ
+vF9K8xJNM+fcsDjpcdjv0P2eH9Bau6k6kdgep576rBNbo63ohwv0tfioDaexWUAm
+QnoF5DFm+AXR/ZdfrpMK2UVso98y7hF4gy+6Nhd2mIPWCPsxDoF9V4AQPN4NSw0C
+AwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5l
+cmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFCDOolSZzyKaXLvUHrAeQ3Njcqre
+MB8GA1UdIwQYMBaAFLCfZzMsiIiJH0RidJ0l/8AGE13WMA0GCSqGSIb3DQEBCwUA
+A4IBgQBlrHww0AHO1/8oYWyNmRXORSKKOXCkps5IlONLjL5VxGaWSUlL4EyV/XMC
+VDrfNC+WFkjswiM97rRa3aDJ64X0/ejVj/PczkqIu74ZgT+LDwkjRhTJ9TVazyV8
+kt+5kF3/TyFAnCR8Dx8/YtF7zEB9xmFJ84QmeO2HcAackwWlxH5gPdBKLOTW5TP4
+B91aDpqTF1ApGv9mYdlAp/vMe2K3nSkaKj17k4frUk4AGRk8TXP8Pe3rnZIwvLDt
+URXOtzwACQydbYsryfVm1ElEWD3nYT1rIQX/HVVZ3eSmL+WWguskMy5HYaX4Taut
+/GT4i54OYowWHXkYdBicohnDJA1uRWP5CJJ9RAuWx0iEcpciI78QCtdOQ4rbYM1d
+gF5x+sK2aBDuzCmGFdPZkyrMc4i+n63QxZyk5IY450GEOtDzZx8sQNcEseoyE0ml
+ghqlbD9f3P1VFAOL170BnrzF5KGoqJ28zR9b/N9Ztw2qR6AIzW73yJ3T3U6LqsxU
+IKArY5Y=
+-----END CERTIFICATE-----
diff --git a/tests/testsuites/x.509/client-revoked.csr b/tests/testsuites/x.509/client-revoked.csr
new file mode 100644
index 0000000..bc99a28
--- /dev/null
+++ b/tests/testsuites/x.509/client-revoked.csr
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIC9DCCAdwCAQAwga4xCzAJBgNVBAYTAkRFMQwwCgYDVQQIDANOUlcxGDAWBgNV
+BAcMD0dyb3NzcmluZGVyZmVsZDEVMBMGA1UECgwMQWRpc2NvbiBHbWJIMRAwDgYD
+VQQLDAdyc3lzbG9nMSkwJwYDVQQDDCByc3lzbG9nIHJldm9rZWQgY2VydGlmaWNh
+dGUgdGVzdDEjMCEGCSqGSIb3DQEJARYUYWxvcmJhY2hAYWRpc2Nvbi5jb20wggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC//hRd6ZxsZxU81EmdWyrqQ8K8
+ntA6XlUvaAArC9rcz/fZpxugozHdqAcTntw2dbg06hca9h3bMx5FNoCunJOmAk4m
++AfeHM6e508l11kkSV40RFSHq+BtWiRBGb8zw6UR1lDA920tEgPMC7nqsoVdka2E
+zr6bC8LrAZe4OtwcuNJD6JZe8ITimBh7FcavDLuOmJYhe81vDZ+EWb+RqLpqybxf
+SvMSTTPn3LA46XHY79D9nh/QWrupOpHYHqee+qwTW6Ot6IcL9LX4qA2nsVlAJkJ6
+BeQxZvgF0f2XX66TCtlFbKPfMu4ReIMvujYXdpiD1gj7MQ6BfVeAEDzeDUsNAgMB
+AAGgADANBgkqhkiG9w0BAQsFAAOCAQEASfTlG7UDUb9bgIerIn2kUYTFxZOnvy/M
+cfDM/iH5m3v7IjHV61mI7x7/P+COG6E9MOSS4+VLFjfc8YlQ67zkyrZxa4LMBqUF
+i+oOvTGvTO4ocBlHcoZ53EE5q3sy/yu67ih8jlTbCjtJ6mUOdXDclJimwKir4e+b
+GPpOvLENDfJ5RShJL5cdGXJqv+ZYuZnh4+zq8h4+EQI1BSzPudomSE6d+gf6Ysyg
+lb1YvhlP2phApgHS+3QeLLW8rTgPheFJcQbg6Sc+m44jysqjOVKc0+RYCdhqI7a7
+Dk/V/eD1VFOoRrIY2WnpvzE39gpV1fl4bUrrcsMCIBe7F2svdFHMog==
+-----END CERTIFICATE REQUEST-----
diff --git a/tests/testsuites/x.509/client-revoked.pem b/tests/testsuites/x.509/client-revoked.pem
new file mode 100644
index 0000000..b64b2a9
--- /dev/null
+++ b/tests/testsuites/x.509/client-revoked.pem
@@ -0,0 +1,92 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 2 (0x2)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=someName, OU=rsyslog, O=SomeOrg, C=US
+ Validity
+ Not Before: Jul 6 12:59:25 2023 GMT
+ Not After : Jun 12 12:59:25 2123 GMT
+ Subject: C=DE, ST=NRW, O=Adiscon GmbH, OU=rsyslog, CN=rsyslog revoked certificate test/emailAddress=alorbach@adiscon.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:bf:fe:14:5d:e9:9c:6c:67:15:3c:d4:49:9d:5b:
+ 2a:ea:43:c2:bc:9e:d0:3a:5e:55:2f:68:00:2b:0b:
+ da:dc:cf:f7:d9:a7:1b:a0:a3:31:dd:a8:07:13:9e:
+ dc:36:75:b8:34:ea:17:1a:f6:1d:db:33:1e:45:36:
+ 80:ae:9c:93:a6:02:4e:26:f8:07:de:1c:ce:9e:e7:
+ 4f:25:d7:59:24:49:5e:34:44:54:87:ab:e0:6d:5a:
+ 24:41:19:bf:33:c3:a5:11:d6:50:c0:f7:6d:2d:12:
+ 03:cc:0b:b9:ea:b2:85:5d:91:ad:84:ce:be:9b:0b:
+ c2:eb:01:97:b8:3a:dc:1c:b8:d2:43:e8:96:5e:f0:
+ 84:e2:98:18:7b:15:c6:af:0c:bb:8e:98:96:21:7b:
+ cd:6f:0d:9f:84:59:bf:91:a8:ba:6a:c9:bc:5f:4a:
+ f3:12:4d:33:e7:dc:b0:38:e9:71:d8:ef:d0:fd:9e:
+ 1f:d0:5a:bb:a9:3a:91:d8:1e:a7:9e:fa:ac:13:5b:
+ a3:ad:e8:87:0b:f4:b5:f8:a8:0d:a7:b1:59:40:26:
+ 42:7a:05:e4:31:66:f8:05:d1:fd:97:5f:ae:93:0a:
+ d9:45:6c:a3:df:32:ee:11:78:83:2f:ba:36:17:76:
+ 98:83:d6:08:fb:31:0e:81:7d:57:80:10:3c:de:0d:
+ 4b:0d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 20:CE:A2:54:99:CF:22:9A:5C:BB:D4:1E:B0:1E:43:73:63:72:AA:DE
+ X509v3 Authority Key Identifier:
+ keyid:B0:9F:67:33:2C:88:88:89:1F:44:62:74:9D:25:FF:C0:06:13:5D:D6
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 33:65:28:98:94:9b:f5:57:0d:bf:02:c2:67:93:8e:8e:77:03:
+ 9b:c7:7a:47:53:29:a4:dd:a6:a1:5e:2a:0a:ed:19:02:80:90:
+ b3:97:1f:06:4c:9c:c5:5f:6c:16:f9:12:fb:dd:da:29:88:b7:
+ 2c:91:0b:ab:53:79:7a:6e:76:20:fe:fa:b1:99:c2:2b:50:26:
+ 7b:cc:8c:75:98:35:95:79:56:43:90:a0:95:5e:98:09:10:4d:
+ ea:c0:1c:bb:c0:7b:a7:8a:9b:21:70:85:65:83:4d:ee:65:ef:
+ 10:d3:63:95:fd:51:9d:6c:41:7b:af:af:9c:e7:34:74:a1:7a:
+ 86:0a:8e:f2:2a:06:68:77:76:fa:fc:64:bc:28:1d:8b:53:7a:
+ cf:62:0f:87:a9:85:54:8c:a5:41:c3:61:0b:cf:96:c1:fa:81:
+ a5:31:63:f3:cb:17:37:58:6e:d9:30:97:fb:57:2f:31:63:e8:
+ 26:0e:82:49:e2:a9:9b:ed:39:7b:24:4e:42:8d:34:74:3a:dc:
+ b7:c5:d6:15:e9:66:28:2d:3c:e0:26:44:76:66:4a:32:94:11:
+ c8:1f:1c:b2:dc:44:69:63:f7:2d:87:b5:89:4a:40:fb:e4:14:
+ 68:dc:8a:76:40:93:35:e2:ac:9a:4b:bc:af:c5:8a:8a:38:54:
+ ef:69:01:4c:92:af:c0:07:d0:2f:7a:3c:9e:40:ac:56:07:d0:
+ 2b:1f:5f:d0:44:f9:70:e1:44:44:34:ba:fb:3d:54:85:4b:1d:
+ ba:ea:ea:6a:91:0c:08:30:2d:bc:b8:ea:22:c1:16:7b:53:fe:
+ 40:2c:8d:f5:c6:c2:39:e6:11:1d:e2:2f:50:a6:76:9c:fd:b9:
+ fa:d5:10:79:0e:e5:02:87:7d:96:e3:81:05:79:c9:a3:d8:f2:
+ a0:b1:8b:0e:8d:33:73:15:6f:27:88:85:03:8a:c5:7a:77:f4:
+ 3f:7f:b8:65:97:5b:a0:a6:21:48:67:2c:a2:73:a2:ec:d6:6a:
+ bd:d6:f2:e2:b1:5b
+-----BEGIN CERTIFICATE-----
+MIIEUTCCArmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBEMREwDwYDVQQDEwhzb21l
+TmFtZTEQMA4GA1UECxMHcnN5c2xvZzEQMA4GA1UEChMHU29tZU9yZzELMAkGA1UE
+BhMCVVMwIBcNMjMwNzA2MTI1OTI1WhgPMjEyMzA2MTIxMjU5MjVaMIGUMQswCQYD
+VQQGEwJERTEMMAoGA1UECAwDTlJXMRUwEwYDVQQKDAxBZGlzY29uIEdtYkgxEDAO
+BgNVBAsMB3JzeXNsb2cxKTAnBgNVBAMMIHJzeXNsb2cgcmV2b2tlZCBjZXJ0aWZp
+Y2F0ZSB0ZXN0MSMwIQYJKoZIhvcNAQkBFhRhbG9yYmFjaEBhZGlzY29uLmNvbTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/+FF3pnGxnFTzUSZ1bKupD
+wrye0DpeVS9oACsL2tzP99mnG6CjMd2oBxOe3DZ1uDTqFxr2HdszHkU2gK6ck6YC
+Tib4B94czp7nTyXXWSRJXjREVIer4G1aJEEZvzPDpRHWUMD3bS0SA8wLueqyhV2R
+rYTOvpsLwusBl7g63By40kPoll7whOKYGHsVxq8Mu46YliF7zW8Nn4RZv5GoumrJ
+vF9K8xJNM+fcsDjpcdjv0P2eH9Bau6k6kdgep576rBNbo63ohwv0tfioDaexWUAm
+QnoF5DFm+AXR/ZdfrpMK2UVso98y7hF4gy+6Nhd2mIPWCPsxDoF9V4AQPN4NSw0C
+AwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5l
+cmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFCDOolSZzyKaXLvUHrAeQ3Njcqre
+MB8GA1UdIwQYMBaAFLCfZzMsiIiJH0RidJ0l/8AGE13WMA0GCSqGSIb3DQEBCwUA
+A4IBgQAzZSiYlJv1Vw2/AsJnk46OdwObx3pHUymk3aahXioK7RkCgJCzlx8GTJzF
+X2wW+RL73dopiLcskQurU3l6bnYg/vqxmcIrUCZ7zIx1mDWVeVZDkKCVXpgJEE3q
+wBy7wHunipshcIVlg03uZe8Q02OV/VGdbEF7r6+c5zR0oXqGCo7yKgZod3b6/GS8
+KB2LU3rPYg+HqYVUjKVBw2ELz5bB+oGlMWPzyxc3WG7ZMJf7Vy8xY+gmDoJJ4qmb
+7Tl7JE5CjTR0Oty3xdYV6WYoLTzgJkR2ZkoylBHIHxyy3ERpY/cth7WJSkD75BRo
+3Ip2QJM14qyaS7yvxYqKOFTvaQFMkq/AB9AvejyeQKxWB9ArH1/QRPlw4URENLr7
+PVSFSx266upqkQwIMC28uOoiwRZ7U/5ALI31xsI55hEd4i9Qpnac/bn61RB5DuUC
+h32W44EFecmj2PKgsYsOjTNzFW8niIUDisV6d/Q/f7hll1ugpiFIZyyic6Ls1mq9
+1vLisVs=
+-----END CERTIFICATE-----
diff --git a/tests/testsuites/x.509/crl.pem b/tests/testsuites/x.509/crl.pem
new file mode 100644
index 0000000..23a1a83
--- /dev/null
+++ b/tests/testsuites/x.509/crl.pem
@@ -0,0 +1,14 @@
+-----BEGIN X509 CRL-----
+MIICIjCBizANBgkqhkiG9w0BAQsFADBEMREwDwYDVQQDEwhzb21lTmFtZTEQMA4G
+A1UECxMHcnN5c2xvZzEQMA4GA1UEChMHU29tZU9yZzELMAkGA1UEBhMCVVMXDTIz
+MDcxMTA3NTEyM1oYDzIxMjMwNjE3MDc1MTIzWjAUMBICAQIXDTIzMDcwNjEzMDEw
+MFowDQYJKoZIhvcNAQELBQADggGBAA4MRtKKvN+qIIULqf80EG3Zy+6BhPc+4GGD
+bB6tHzBf/G+S931yxQB6yXgoHv9SdR0ZDj28gGG0c6YBYiBID6MecRreEZkBzbNg
+3YsLpAQsE9ZO6pBancjbkhg3ikdACBaWrsQLFaVsZCGyAJN5kL0jzE/aoGmvKLpQ
+NXmQo3+/IuJ+jes/vEcG6LyCyr0LKbbFNdj/VsF7KIRjY2BP995rz/X6mWoS8fP0
+hIE3G4NC+BeWBAi/txwlkxl8AXsQW+AZNCFR9/9k1LIBE/5MY4rEn60PoR4QIqja
+cKdEkhvkBM8gNkthKplA1wfDMXzhXilwW4uRjF//Oiz97rBg4JYkNw1hEsK97SPT
+E2dtXZ2I0mBR32twVRvRdp14VHGo/EHPnTPBwJZSuiKPCQjGX61xzJdHfu1oGpW+
+E3R4AWlfzpUnCeA3uERsukJbdJmgPYz4tkfSil2//9wHLxuJHokl3wrQ87Rt+YDB
+CnYqvamCfmQQeXp1waXOE94lTLV0RA==
+-----END X509 CRL-----
diff --git a/tests/testsuites/x.509/index.txt b/tests/testsuites/x.509/index.txt
new file mode 100644
index 0000000..ee97457
--- /dev/null
+++ b/tests/testsuites/x.509/index.txt
@@ -0,0 +1,3 @@
+R 21230612125925Z 230706130100Z 02 unknown /C=DE/ST=NRW/O=Adiscon GmbH/OU=rsyslog/CN=rsyslog revoked certificate test/emailAddress=alorbach@adiscon.com
+V 21230612133806Z 03 unknown /C=DE/ST=NRW/O=Adiscon GmbH/OU=rsyslog/CN=rsyslog revoked certificate test/emailAddress=alorbach@adiscon.com
+V 21230612135250Z 04 unknown /C=US/ST=CA/O=SomeComp/OU=SomeUnit/CN=rsyslog/emailAddress=alorbach@adiscon.com
diff --git a/tests/testsuites/x.509/index.txt.attr b/tests/testsuites/x.509/index.txt.attr
new file mode 100644
index 0000000..8f7e63a
--- /dev/null
+++ b/tests/testsuites/x.509/index.txt.attr
@@ -0,0 +1 @@
+unique_subject = yes
diff --git a/tests/testsuites/x.509/machine-cert.pem b/tests/testsuites/x.509/machine-cert.pem
new file mode 100644
index 0000000..def6e7e
--- /dev/null
+++ b/tests/testsuites/x.509/machine-cert.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEmjCCAwKgAwIBAgIIXBegQDWsgowwDQYJKoZIhvcNAQELBQAwRDERMA8GA1UE
+AxMIc29tZU5hbWUxEDAOBgNVBAsTB3JzeXNsb2cxEDAOBgNVBAoTB1NvbWVPcmcx
+CzAJBgNVBAYTAlVTMCAXDTE4MTIxNzEzMTAyNloYDzIxMTgxMTIzMTMxMDI4WjBR
+MQ8wDQYDVQQLEwZTb21lT1UxEDAOBgNVBAoTB1NvbWVPcmcxEjAQBgNVBAcTCVNv
+bWV3aGVyZTELMAkGA1UECBMCQ0ExCzAJBgNVBAYTAlVTMIIBojANBgkqhkiG9w0B
+AQEFAAOCAY8AMIIBigKCAYEAvYhZDSdPcxBgjF+sgQZ10YPuIXIzoiq4G943OGFX
+EdMc0kdaVQcCKkR4raPMR0wKs57akpiN5CrU1HvkwYZbTNB/BpyhUuZnx2qjTRyO
+pB71k62z7HP3KAI/GYfEMX5DNPS0X3B7chkAT4Sk1Xdn3WjW3BVt3GK4XdWmG2M0
+cmsYaFvijFJDi6Fs8fy/5sG2x+WBwct1Kt8HnjfR+nh00YhgiqOdX1jOrDN29XHk
+n4GIEm/BRQRQ0/PoOa6VWGVVxu+8sfmM7IJ8kC5/QII3PFZCplqPnxFYd3C0Wa6v
+au+tYisJ9B5CB/fn9ars7H6nFMc1D38G/sVkspdJrFuFbQLElkH7ydxBZBv3O+fl
+Iomav/+JL1PiNHFtXxoGsTOPHHFKbqauxLuTbv9B5D1tO/MaxOBTt9MVMx8rDpVB
+y0spKhfWcxJ/0Hge7G9XrFGpN4joBPHPMghM8QjS9/EL8r98m8PNQk6OIG9TNeQC
+gzglQIV3K+rhFwTeeyetxDozAgMBAAGjgYAwfjAMBgNVHRMBAf8EAjAAMB0GA1Ud
+JQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHQ8BAf8EBQMDB6AAMB0GA1Ud
+DgQWBBQ3rDq/2kYOFskMD0lHFG+g2Ej/2zAfBgNVHSMEGDAWgBSwn2czLIiIiR9E
+YnSdJf/ABhNd1jANBgkqhkiG9w0BAQsFAAOCAYEARbJDuWZiqwA/CU9Eh99POTOk
+fnWdog8tLaOPLFS5mCiLNDmTXX14syAAjhbRrJ+43j1HWXbgovzDqzFtQzbztCMB
+qpxQy3d3R9nUKv6NpNT/IO84OcYuiMtRGr/AaVqc2PZlFirBqlQkxFUxiDc2pIhy
+h2orOJrPu3jSQdWI1PDT6oWKCwHdU+obqh+NmRWwjetpmeJ5r/kgAlZJ1krlNPJU
+V3U/J9WTdOYMhLcn4RcNOTAyrmxOoTEIOcqkXzJOypbkMcZic+OHCaDohUsfdOkB
+Xxz+6nP4xqnOcyHBLNTjVVrnr+wyqsWA18HoyLiCluf946S6mVoXcxwvWHzz7VVm
+qHVppLVD/iOJxtl4bm8YEYjO4C1IPxWOCszG4N71Reyo/+p1UJ8Ww6IAgJj0jX2l
+L7pqCwZKXhd8+LT05dZr7YJV/EjmGV/pL6IU3RAk6s2BqgtTkvy5nnmSPjBFuxG/
+gUBfaglsXC6w6R1aMVr9m3E1ht4vOPu9Qx7E21oG
+-----END CERTIFICATE-----
diff --git a/tests/testsuites/x.509/machine-key.pem b/tests/testsuites/x.509/machine-key.pem
new file mode 100644
index 0000000..2958202
--- /dev/null
+++ b/tests/testsuites/x.509/machine-key.pem
@@ -0,0 +1,182 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:bd:88:59:0d:27:4f:73:10:60:8c:5f:ac:81:06:75
+ d1:83:ee:21:72:33:a2:2a:b8:1b:de:37:38:61:57:11
+ d3:1c:d2:47:5a:55:07:02:2a:44:78:ad:a3:cc:47:4c
+ 0a:b3:9e:da:92:98:8d:e4:2a:d4:d4:7b:e4:c1:86:5b
+ 4c:d0:7f:06:9c:a1:52:e6:67:c7:6a:a3:4d:1c:8e:a4
+ 1e:f5:93:ad:b3:ec:73:f7:28:02:3f:19:87:c4:31:7e
+ 43:34:f4:b4:5f:70:7b:72:19:00:4f:84:a4:d5:77:67
+ dd:68:d6:dc:15:6d:dc:62:b8:5d:d5:a6:1b:63:34:72
+ 6b:18:68:5b:e2:8c:52:43:8b:a1:6c:f1:fc:bf:e6:c1
+ b6:c7:e5:81:c1:cb:75:2a:df:07:9e:37:d1:fa:78:74
+ d1:88:60:8a:a3:9d:5f:58:ce:ac:33:76:f5:71:e4:9f
+ 81:88:12:6f:c1:45:04:50:d3:f3:e8:39:ae:95:58:65
+ 55:c6:ef:bc:b1:f9:8c:ec:82:7c:90:2e:7f:40:82:37
+ 3c:56:42:a6:5a:8f:9f:11:58:77:70:b4:59:ae:af:6a
+ ef:ad:62:2b:09:f4:1e:42:07:f7:e7:f5:aa:ec:ec:7e
+ a7:14:c7:35:0f:7f:06:fe:c5:64:b2:97:49:ac:5b:85
+ 6d:02:c4:96:41:fb:c9:dc:41:64:1b:f7:3b:e7:e5:22
+ 89:9a:bf:ff:89:2f:53:e2:34:71:6d:5f:1a:06:b1:33
+ 8f:1c:71:4a:6e:a6:ae:c4:bb:93:6e:ff:41:e4:3d:6d
+ 3b:f3:1a:c4:e0:53:b7:d3:15:33:1f:2b:0e:95:41:cb
+ 4b:29:2a:17:d6:73:12:7f:d0:78:1e:ec:6f:57:ac:51
+ a9:37:88:e8:04:f1:cf:32:08:4c:f1:08:d2:f7:f1:0b
+ f2:bf:7c:9b:c3:cd:42:4e:8e:20:6f:53:35:e4:02:83
+ 38:25:40:85:77:2b:ea:e1:17:04:de:7b:27:ad:c4:3a
+ 33:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 19:dd:b1:c9:89:c3:de:00:2e:2c:fa:21:a0:ba:30:fa
+ 16:f7:38:b9:4d:32:a4:81:db:cb:c7:dd:79:eb:58:13
+ 67:ab:8a:f1:59:09:4b:d2:58:e5:df:4c:ab:64:4f:8c
+ 66:57:17:9d:4a:14:93:3f:05:2c:ba:7b:cd:ad:78:68
+ 53:4c:02:aa:fd:99:42:b8:87:0e:96:9a:bf:7a:f8:0b
+ 01:98:d5:eb:e8:29:2b:61:da:6c:a2:1f:55:37:2b:f4
+ 20:16:05:47:c1:22:17:c0:31:ba:a8:6f:96:72:65:4a
+ 62:34:70:74:bc:39:87:7f:81:ce:d6:8c:86:4d:72:10
+ 0b:94:b2:75:88:90:f1:86:ec:d0:e1:75:8c:fb:01:14
+ e0:d3:01:92:61:21:ec:67:e3:b2:44:0b:f4:12:dc:5e
+ 7c:2e:30:bd:83:8c:af:a2:04:fe:41:0d:de:2d:45:57
+ 78:2a:8b:f5:e4:65:62:62:8a:b6:f6:a8:4c:d9:73:7a
+ b5:15:d0:91:c7:89:a9:45:94:00:0c:1d:69:f0:48:f7
+ 26:83:50:bd:b3:e7:7e:70:8b:21:bf:99:fd:04:d2:8a
+ d2:b1:be:9e:4b:a7:f1:57:8f:34:c0:b9:f0:22:d8:bf
+ 3f:fa:8c:77:47:7d:62:d4:5c:d8:08:1b:dd:3c:a2:c3
+ 60:25:84:be:02:a2:79:00:e4:06:c8:48:49:43:ac:9f
+ 45:78:c9:46:0a:9a:1f:5b:70:d1:da:b6:e6:f1:fc:af
+ a5:85:c6:7b:78:f0:5c:2c:91:1b:ba:36:62:f8:31:ed
+ 21:87:15:49:3c:c1:bf:53:a4:11:9a:19:91:51:aa:49
+ ea:d8:b3:a4:66:76:2a:ad:8e:61:38:f5:7a:ba:59:bb
+ 2e:48:f3:fc:14:a1:42:18:e7:c6:c6:41:03:d4:ca:d6
+ 85:14:cc:8b:1d:57:38:6f:ef:9e:14:34:85:38:92:ab
+ f8:24:f4:5b:14:6b:6a:3c:22:29:bb:36:51:68:43:81
+
+
+prime1:
+ 00:cd:49:91:cb:0a:37:19:fe:50:c0:9a:a0:c3:53:9b
+ fb:3c:e0:dc:2d:55:69:0e:cd:ea:e7:0c:a5:c1:34:a0
+ b5:8d:72:45:da:9c:56:15:8b:31:3f:fb:93:d7:b0:81
+ de:d1:9f:d8:c4:c1:ff:5a:d6:a8:15:c1:b6:c5:11:39
+ 4f:e9:16:06:fb:be:90:d4:a2:9d:23:0a:b3:52:81:07
+ d5:ae:2c:f5:bb:7e:32:62:59:f9:65:1f:ab:9b:3c:67
+ 94:b7:e2:49:69:3d:c6:98:e4:3e:56:f9:0f:02:e1:6c
+ c2:da:10:3b:9d:39:e7:55:40:6d:ae:46:f6:b8:cc:30
+ 2c:26:02:4f:65:a8:7c:38:47:9c:d8:96:ce:31:89:a4
+ 07:91:de:4d:46:35:b0:8e:01:fd:ca:11:c2:c8:8e:71
+ 32:eb:a0:61:da:10:db:8b:4d:ac:29:73:d2:b1:7c:d4
+ d3:0d:ce:a2:88:ef:3b:d0:b4:2b:50:1f:62:c8:e6:d2
+ 7d:
+
+prime2:
+ 00:ec:5a:71:35:ee:17:84:3a:0f:41:9b:44:e6:1e:f3
+ e2:c6:31:09:cd:d6:af:4d:6a:ac:fc:c1:03:40:67:91
+ 73:38:4e:a7:d1:2a:b9:25:a1:da:e9:77:9b:dd:e9:c2
+ 1a:72:0b:11:97:90:04:23:a7:4d:e3:ad:29:6b:65:c6
+ 63:8b:00:65:0a:7e:3d:46:b8:f7:4b:eb:a4:ee:cf:19
+ 3e:a0:52:80:72:e7:9f:9c:8b:b1:d0:0b:e3:9c:34:1e
+ d2:7c:ac:e2:c2:90:69:2b:78:9c:c1:9a:84:7a:5b:dc
+ 99:83:a0:18:22:fc:30:c6:7e:1e:97:de:bc:66:71:26
+ ec:f2:98:06:ce:62:53:d7:af:86:21:07:95:98:2c:2a
+ f4:4e:fe:58:a7:97:19:de:5a:4a:94:ee:98:d3:a0:77
+ 9e:db:52:55:64:a4:fa:84:c3:a8:89:8a:97:22:93:a6
+ f0:00:85:38:91:7a:52:98:2f:34:10:7e:92:9d:76:ae
+ 6f:
+
+coefficient:
+ 00:94:fa:06:8f:7e:8a:1d:be:16:55:80:93:01:0d:ab
+ 77:4b:d3:a5:14:37:ef:04:28:b3:91:d9:5f:df:e8:56
+ d5:1d:bd:c1:25:e8:bf:69:49:04:2f:c1:73:73:27:64
+ 66:3e:61:20:d5:25:db:ad:da:3d:e8:a3:a5:20:16:38
+ 6b:28:18:83:97:07:67:6a:16:4b:7f:2b:da:6a:a5:1b
+ ec:9a:c3:2a:4f:5d:9e:7e:9b:05:a5:a8:bb:ab:76:27
+ 1a:07:27:be:c8:65:94:e8:54:41:ba:1f:b3:91:5d:b1
+ 5a:13:2b:b3:11:60:52:26:47:35:a7:46:bd:16:f9:e5
+ 1e:4b:e9:48:33:aa:33:30:77:8e:71:e4:88:1c:1a:57
+ af:17:77:76:65:d2:2b:a3:33:b8:ec:34:f8:23:03:5b
+ 90:cb:eb:a4:c0:ee:98:0f:9c:5e:73:11:bd:9e:01:99
+ 79:4f:98:1e:12:25:62:88:3a:65:12:8f:67:45:40:af
+ 4b:
+
+exp1:
+ 30:f9:93:39:a0:47:43:01:44:1c:9f:07:29:72:41:ed
+ 2f:39:e9:ed:3a:ca:24:89:05:b8:77:70:f7:e5:e9:4d
+ 46:e0:73:3f:d3:3a:4a:4b:79:c5:6c:ec:79:71:97:9a
+ 23:e2:81:a1:77:32:c7:66:1c:95:8c:30:61:55:59:99
+ f1:de:9a:6d:e6:a9:c0:c0:c6:c2:3c:64:49:93:94:dd
+ ea:7e:b9:65:30:97:2e:95:8e:85:0c:88:31:31:b8:f8
+ 66:e2:2a:67:5c:20:8c:0b:2f:c0:2a:0c:e5:c0:07:e5
+ 78:86:94:e2:4e:95:1c:e6:91:04:19:d3:f4:84:6a:1d
+ ae:37:b0:df:6c:d1:ad:cf:8f:e0:b0:21:a2:f9:d6:53
+ 23:fe:a7:ea:cf:16:3e:da:c4:c4:37:76:83:c8:4f:c3
+ 39:29:7b:0e:be:24:d2:58:06:71:a1:3b:2b:b2:bf:47
+ 56:ac:ec:63:c4:c7:3d:64:2e:4d:20:1f:be:14:2b:35
+
+
+exp2:
+ 11:dd:bc:55:11:4c:61:c8:69:c2:d1:d3:e1:79:51:82
+ 40:ed:10:0a:a9:41:d3:1e:4f:39:43:f5:d4:f6:7f:3e
+ 30:71:71:aa:14:0a:ae:d7:8f:4e:ba:a5:e3:9e:79:f7
+ b9:cb:30:67:3e:91:b1:88:42:11:05:d3:ed:b4:61:cc
+ c0:83:25:20:27:ee:c5:db:d1:85:c1:a8:54:0c:ff:a1
+ 86:48:f6:40:b9:55:8d:65:d9:e9:1a:1c:f8:7f:d0:1c
+ a5:24:04:78:24:a6:6e:8c:cd:7c:ad:0b:7a:9c:5b:0e
+ 97:ae:90:64:84:9f:c3:41:61:5a:a5:91:a4:44:c5:66
+ 7f:e8:12:0b:a3:cf:26:ac:b3:fc:e7:2f:dd:b2:e9:04
+ 52:bc:53:43:47:de:c2:ba:1c:8d:29:84:0f:eb:3f:5f
+ 98:c0:9e:87:df:18:b8:d4:79:76:fc:2c:f4:86:28:c6
+ 57:a3:ba:64:f4:d4:2d:80:d3:f4:b3:3c:ad:fe:7c:ad
+
+
+
+Public Key PIN:
+ pin-sha256:P26XjPq8H830hYvKjSgxiVfBDOiZNDGexDfrJkKWi9o=
+Public Key ID:
+ sha256:3f6e978cfabc1fcdf4858bca8d28318957c10ce89934319ec437eb2642968bda
+ sha1:37ac3abfda460e16c90c0f4947146fa0d848ffdb
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4wIBAAKCAYEAvYhZDSdPcxBgjF+sgQZ10YPuIXIzoiq4G943OGFXEdMc0kda
+VQcCKkR4raPMR0wKs57akpiN5CrU1HvkwYZbTNB/BpyhUuZnx2qjTRyOpB71k62z
+7HP3KAI/GYfEMX5DNPS0X3B7chkAT4Sk1Xdn3WjW3BVt3GK4XdWmG2M0cmsYaFvi
+jFJDi6Fs8fy/5sG2x+WBwct1Kt8HnjfR+nh00YhgiqOdX1jOrDN29XHkn4GIEm/B
+RQRQ0/PoOa6VWGVVxu+8sfmM7IJ8kC5/QII3PFZCplqPnxFYd3C0Wa6vau+tYisJ
+9B5CB/fn9ars7H6nFMc1D38G/sVkspdJrFuFbQLElkH7ydxBZBv3O+flIomav/+J
+L1PiNHFtXxoGsTOPHHFKbqauxLuTbv9B5D1tO/MaxOBTt9MVMx8rDpVBy0spKhfW
+cxJ/0Hge7G9XrFGpN4joBPHPMghM8QjS9/EL8r98m8PNQk6OIG9TNeQCgzglQIV3
+K+rhFwTeeyetxDozAgMBAAECggGAGd2xyYnD3gAuLPohoLow+hb3OLlNMqSB28vH
+3XnrWBNnq4rxWQlL0ljl30yrZE+MZlcXnUoUkz8FLLp7za14aFNMAqr9mUK4hw6W
+mr96+AsBmNXr6CkrYdpsoh9VNyv0IBYFR8EiF8AxuqhvlnJlSmI0cHS8OYd/gc7W
+jIZNchALlLJ1iJDxhuzQ4XWM+wEU4NMBkmEh7GfjskQL9BLcXnwuML2DjK+iBP5B
+Dd4tRVd4Kov15GViYoq29qhM2XN6tRXQkceJqUWUAAwdafBI9yaDUL2z535wiyG/
+mf0E0orSsb6eS6fxV480wLnwIti/P/qMd0d9YtRc2Agb3Tyiw2AlhL4ConkA5AbI
+SElDrJ9FeMlGCpofW3DR2rbm8fyvpYXGe3jwXCyRG7o2Yvgx7SGHFUk8wb9TpBGa
+GZFRqknq2LOkZnYqrY5hOPV6ulm7Lkjz/BShQhjnxsZBA9TK1oUUzIsdVzhv754U
+NIU4kqv4JPRbFGtqPCIpuzZRaEOBAoHBAM1JkcsKNxn+UMCaoMNTm/s84NwtVWkO
+zernDKXBNKC1jXJF2pxWFYsxP/uT17CB3tGf2MTB/1rWqBXBtsUROU/pFgb7vpDU
+op0jCrNSgQfVriz1u34yYln5ZR+rmzxnlLfiSWk9xpjkPlb5DwLhbMLaEDudOedV
+QG2uRva4zDAsJgJPZah8OEec2JbOMYmkB5HeTUY1sI4B/coRwsiOcTLroGHaENuL
+Tawpc9KxfNTTDc6iiO870LQrUB9iyObSfQKBwQDsWnE17heEOg9Bm0TmHvPixjEJ
+zdavTWqs/MEDQGeRczhOp9EquSWh2ul3m93pwhpyCxGXkAQjp03jrSlrZcZjiwBl
+Cn49Rrj3S+uk7s8ZPqBSgHLnn5yLsdAL45w0HtJ8rOLCkGkreJzBmoR6W9yZg6AY
+Ivwwxn4el968ZnEm7PKYBs5iU9evhiEHlZgsKvRO/linlxneWkqU7pjToHee21JV
+ZKT6hMOoiYqXIpOm8ACFOJF6UpgvNBB+kp12rm8CgcAw+ZM5oEdDAUQcnwcpckHt
+Lznp7TrKJIkFuHdw9+XpTUbgcz/TOkpLecVs7Hlxl5oj4oGhdzLHZhyVjDBhVVmZ
+8d6abeapwMDGwjxkSZOU3ep+uWUwly6VjoUMiDExuPhm4ipnXCCMCy/AKgzlwAfl
+eIaU4k6VHOaRBBnT9IRqHa43sN9s0a3Pj+CwIaL51lMj/qfqzxY+2sTEN3aDyE/D
+OSl7Dr4k0lgGcaE7K7K/R1as7GPExz1kLk0gH74UKzUCgcAR3bxVEUxhyGnC0dPh
+eVGCQO0QCqlB0x5POUP11PZ/PjBxcaoUCq7Xj066peOeefe5yzBnPpGxiEIRBdPt
+tGHMwIMlICfuxdvRhcGoVAz/oYZI9kC5VY1l2ekaHPh/0BylJAR4JKZujM18rQt6
+nFsOl66QZISfw0FhWqWRpETFZn/oEgujzyass/znL92y6QRSvFNDR97CuhyNKYQP
+6z9fmMCeh98YuNR5dvws9IYoxlejumT01C2A0/SzPK3+fK0CgcEAlPoGj36KHb4W
+VYCTAQ2rd0vTpRQ37wQos5HZX9/oVtUdvcEl6L9pSQQvwXNzJ2RmPmEg1SXbrdo9
+6KOlIBY4aygYg5cHZ2oWS38r2mqlG+yawypPXZ5+mwWlqLurdicaBye+yGWU6FRB
+uh+zkV2xWhMrsxFgUiZHNadGvRb55R5L6UgzqjMwd45x5IgcGlevF3d2ZdIrozO4
+7DT4IwNbkMvrpMDumA+cXnMRvZ4BmXlPmB4SJWKIOmUSj2dFQK9L
+-----END RSA PRIVATE KEY-----
diff --git a/tests/testsuites/x.509/newcerts/01.pem b/tests/testsuites/x.509/newcerts/01.pem
new file mode 100644
index 0000000..b4bf169
--- /dev/null
+++ b/tests/testsuites/x.509/newcerts/01.pem
@@ -0,0 +1,92 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=someName, OU=rsyslog, O=SomeOrg, C=US
+ Validity
+ Not Before: Jul 6 12:57:29 2023 GMT
+ Not After : Jun 12 12:57:29 2123 GMT
+ Subject: C=DE, ST=NRW, O=Adiscon GmbH, OU=rsyslog, CN=rsyslog revoked certificate test/emailAddress=alorbach@adiscon.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:bf:fe:14:5d:e9:9c:6c:67:15:3c:d4:49:9d:5b:
+ 2a:ea:43:c2:bc:9e:d0:3a:5e:55:2f:68:00:2b:0b:
+ da:dc:cf:f7:d9:a7:1b:a0:a3:31:dd:a8:07:13:9e:
+ dc:36:75:b8:34:ea:17:1a:f6:1d:db:33:1e:45:36:
+ 80:ae:9c:93:a6:02:4e:26:f8:07:de:1c:ce:9e:e7:
+ 4f:25:d7:59:24:49:5e:34:44:54:87:ab:e0:6d:5a:
+ 24:41:19:bf:33:c3:a5:11:d6:50:c0:f7:6d:2d:12:
+ 03:cc:0b:b9:ea:b2:85:5d:91:ad:84:ce:be:9b:0b:
+ c2:eb:01:97:b8:3a:dc:1c:b8:d2:43:e8:96:5e:f0:
+ 84:e2:98:18:7b:15:c6:af:0c:bb:8e:98:96:21:7b:
+ cd:6f:0d:9f:84:59:bf:91:a8:ba:6a:c9:bc:5f:4a:
+ f3:12:4d:33:e7:dc:b0:38:e9:71:d8:ef:d0:fd:9e:
+ 1f:d0:5a:bb:a9:3a:91:d8:1e:a7:9e:fa:ac:13:5b:
+ a3:ad:e8:87:0b:f4:b5:f8:a8:0d:a7:b1:59:40:26:
+ 42:7a:05:e4:31:66:f8:05:d1:fd:97:5f:ae:93:0a:
+ d9:45:6c:a3:df:32:ee:11:78:83:2f:ba:36:17:76:
+ 98:83:d6:08:fb:31:0e:81:7d:57:80:10:3c:de:0d:
+ 4b:0d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 20:CE:A2:54:99:CF:22:9A:5C:BB:D4:1E:B0:1E:43:73:63:72:AA:DE
+ X509v3 Authority Key Identifier:
+ keyid:B0:9F:67:33:2C:88:88:89:1F:44:62:74:9D:25:FF:C0:06:13:5D:D6
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 60:37:92:c5:17:64:ed:64:a3:28:c2:81:60:a2:20:ac:e4:2d:
+ ce:bd:4b:4c:6e:ea:70:a1:2c:2d:d9:1c:94:cb:d1:81:ca:53:
+ c2:51:24:af:da:af:90:11:98:52:da:25:2b:19:59:82:58:d6:
+ 84:a5:63:d4:89:05:a9:12:bf:5d:8b:c8:1f:27:b0:a7:65:7e:
+ 0c:18:b7:3d:4e:ec:c5:34:b3:d3:92:f7:de:e5:19:1b:b9:e8:
+ 47:a7:ca:22:13:c4:63:4f:44:09:70:e2:90:f3:a7:5e:e0:5d:
+ 9c:f7:be:ea:1e:88:e7:c2:d3:b6:35:6d:b0:3b:84:8f:03:94:
+ a8:c0:c1:ed:27:17:9a:4d:f7:33:23:1e:76:3a:63:38:f0:59:
+ 39:98:ce:89:4b:2a:89:0e:12:bf:25:b5:d6:04:20:88:f0:65:
+ 9d:70:90:67:e8:28:8e:09:fa:d9:ab:c9:a9:0f:28:63:10:bb:
+ 24:2d:44:2f:6b:fb:7c:d2:38:01:ab:d2:33:2d:50:f4:75:80:
+ 9e:4f:d2:26:6c:31:23:44:8e:d5:a3:51:56:cf:d9:38:f6:d0:
+ 84:c0:fb:6f:c1:66:9c:e7:dd:51:4f:42:bb:d7:cc:ba:35:e1:
+ c6:a2:5c:4b:f2:1e:b7:e2:52:a5:83:97:ab:42:09:54:04:ed:
+ 4f:01:2d:cf:ee:44:b4:da:39:5c:da:30:d5:92:b6:04:11:8b:
+ 04:d7:6a:3a:28:6e:54:97:97:99:a3:ba:3a:48:1a:17:ef:49:
+ 05:fd:c5:e6:3f:c1:7c:ac:b0:45:62:ff:15:fd:13:1b:04:ba:
+ 72:23:32:0a:b8:4d:39:9a:31:15:4c:0a:d0:ef:a2:82:8f:2e:
+ ad:3c:23:dd:59:12:08:6f:e0:5b:5e:5c:29:db:74:ff:8c:08:
+ 43:59:6a:a1:57:df:37:02:53:16:14:f7:c5:4b:47:61:1e:86:
+ aa:2d:46:4d:b3:85:8a:ac:c3:8c:b5:87:90:01:4c:33:91:96:
+ 38:95:06:a7:36:90
+-----BEGIN CERTIFICATE-----
+MIIEUTCCArmgAwIBAgIBATANBgkqhkiG9w0BAQsFADBEMREwDwYDVQQDEwhzb21l
+TmFtZTEQMA4GA1UECxMHcnN5c2xvZzEQMA4GA1UEChMHU29tZU9yZzELMAkGA1UE
+BhMCVVMwIBcNMjMwNzA2MTI1NzI5WhgPMjEyMzA2MTIxMjU3MjlaMIGUMQswCQYD
+VQQGEwJERTEMMAoGA1UECAwDTlJXMRUwEwYDVQQKDAxBZGlzY29uIEdtYkgxEDAO
+BgNVBAsMB3JzeXNsb2cxKTAnBgNVBAMMIHJzeXNsb2cgcmV2b2tlZCBjZXJ0aWZp
+Y2F0ZSB0ZXN0MSMwIQYJKoZIhvcNAQkBFhRhbG9yYmFjaEBhZGlzY29uLmNvbTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/+FF3pnGxnFTzUSZ1bKupD
+wrye0DpeVS9oACsL2tzP99mnG6CjMd2oBxOe3DZ1uDTqFxr2HdszHkU2gK6ck6YC
+Tib4B94czp7nTyXXWSRJXjREVIer4G1aJEEZvzPDpRHWUMD3bS0SA8wLueqyhV2R
+rYTOvpsLwusBl7g63By40kPoll7whOKYGHsVxq8Mu46YliF7zW8Nn4RZv5GoumrJ
+vF9K8xJNM+fcsDjpcdjv0P2eH9Bau6k6kdgep576rBNbo63ohwv0tfioDaexWUAm
+QnoF5DFm+AXR/ZdfrpMK2UVso98y7hF4gy+6Nhd2mIPWCPsxDoF9V4AQPN4NSw0C
+AwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5l
+cmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFCDOolSZzyKaXLvUHrAeQ3Njcqre
+MB8GA1UdIwQYMBaAFLCfZzMsiIiJH0RidJ0l/8AGE13WMA0GCSqGSIb3DQEBCwUA
+A4IBgQBgN5LFF2TtZKMowoFgoiCs5C3OvUtMbupwoSwt2RyUy9GBylPCUSSv2q+Q
+EZhS2iUrGVmCWNaEpWPUiQWpEr9di8gfJ7CnZX4MGLc9TuzFNLPTkvfe5RkbuehH
+p8oiE8RjT0QJcOKQ86de4F2c977qHojnwtO2NW2wO4SPA5SowMHtJxeaTfczIx52
+OmM48Fk5mM6JSyqJDhK/JbXWBCCI8GWdcJBn6CiOCfrZq8mpDyhjELskLUQva/t8
+0jgBq9IzLVD0dYCeT9ImbDEjRI7Vo1FWz9k49tCEwPtvwWac591RT0K718y6NeHG
+olxL8h634lKlg5erQglUBO1PAS3P7kS02jlc2jDVkrYEEYsE12o6KG5Ul5eZo7o6
+SBoX70kF/cXmP8F8rLBFYv8V/RMbBLpyIzIKuE05mjEVTArQ76KCjy6tPCPdWRII
+b+BbXlwp23T/jAhDWWqhV983AlMWFPfFS0dhHoaqLUZNs4WKrMOMtYeQAUwzkZY4
+lQanNpA=
+-----END CERTIFICATE-----
diff --git a/tests/testsuites/x.509/newcerts/02.pem b/tests/testsuites/x.509/newcerts/02.pem
new file mode 100644
index 0000000..b64b2a9
--- /dev/null
+++ b/tests/testsuites/x.509/newcerts/02.pem
@@ -0,0 +1,92 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 2 (0x2)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=someName, OU=rsyslog, O=SomeOrg, C=US
+ Validity
+ Not Before: Jul 6 12:59:25 2023 GMT
+ Not After : Jun 12 12:59:25 2123 GMT
+ Subject: C=DE, ST=NRW, O=Adiscon GmbH, OU=rsyslog, CN=rsyslog revoked certificate test/emailAddress=alorbach@adiscon.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:bf:fe:14:5d:e9:9c:6c:67:15:3c:d4:49:9d:5b:
+ 2a:ea:43:c2:bc:9e:d0:3a:5e:55:2f:68:00:2b:0b:
+ da:dc:cf:f7:d9:a7:1b:a0:a3:31:dd:a8:07:13:9e:
+ dc:36:75:b8:34:ea:17:1a:f6:1d:db:33:1e:45:36:
+ 80:ae:9c:93:a6:02:4e:26:f8:07:de:1c:ce:9e:e7:
+ 4f:25:d7:59:24:49:5e:34:44:54:87:ab:e0:6d:5a:
+ 24:41:19:bf:33:c3:a5:11:d6:50:c0:f7:6d:2d:12:
+ 03:cc:0b:b9:ea:b2:85:5d:91:ad:84:ce:be:9b:0b:
+ c2:eb:01:97:b8:3a:dc:1c:b8:d2:43:e8:96:5e:f0:
+ 84:e2:98:18:7b:15:c6:af:0c:bb:8e:98:96:21:7b:
+ cd:6f:0d:9f:84:59:bf:91:a8:ba:6a:c9:bc:5f:4a:
+ f3:12:4d:33:e7:dc:b0:38:e9:71:d8:ef:d0:fd:9e:
+ 1f:d0:5a:bb:a9:3a:91:d8:1e:a7:9e:fa:ac:13:5b:
+ a3:ad:e8:87:0b:f4:b5:f8:a8:0d:a7:b1:59:40:26:
+ 42:7a:05:e4:31:66:f8:05:d1:fd:97:5f:ae:93:0a:
+ d9:45:6c:a3:df:32:ee:11:78:83:2f:ba:36:17:76:
+ 98:83:d6:08:fb:31:0e:81:7d:57:80:10:3c:de:0d:
+ 4b:0d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 20:CE:A2:54:99:CF:22:9A:5C:BB:D4:1E:B0:1E:43:73:63:72:AA:DE
+ X509v3 Authority Key Identifier:
+ keyid:B0:9F:67:33:2C:88:88:89:1F:44:62:74:9D:25:FF:C0:06:13:5D:D6
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 33:65:28:98:94:9b:f5:57:0d:bf:02:c2:67:93:8e:8e:77:03:
+ 9b:c7:7a:47:53:29:a4:dd:a6:a1:5e:2a:0a:ed:19:02:80:90:
+ b3:97:1f:06:4c:9c:c5:5f:6c:16:f9:12:fb:dd:da:29:88:b7:
+ 2c:91:0b:ab:53:79:7a:6e:76:20:fe:fa:b1:99:c2:2b:50:26:
+ 7b:cc:8c:75:98:35:95:79:56:43:90:a0:95:5e:98:09:10:4d:
+ ea:c0:1c:bb:c0:7b:a7:8a:9b:21:70:85:65:83:4d:ee:65:ef:
+ 10:d3:63:95:fd:51:9d:6c:41:7b:af:af:9c:e7:34:74:a1:7a:
+ 86:0a:8e:f2:2a:06:68:77:76:fa:fc:64:bc:28:1d:8b:53:7a:
+ cf:62:0f:87:a9:85:54:8c:a5:41:c3:61:0b:cf:96:c1:fa:81:
+ a5:31:63:f3:cb:17:37:58:6e:d9:30:97:fb:57:2f:31:63:e8:
+ 26:0e:82:49:e2:a9:9b:ed:39:7b:24:4e:42:8d:34:74:3a:dc:
+ b7:c5:d6:15:e9:66:28:2d:3c:e0:26:44:76:66:4a:32:94:11:
+ c8:1f:1c:b2:dc:44:69:63:f7:2d:87:b5:89:4a:40:fb:e4:14:
+ 68:dc:8a:76:40:93:35:e2:ac:9a:4b:bc:af:c5:8a:8a:38:54:
+ ef:69:01:4c:92:af:c0:07:d0:2f:7a:3c:9e:40:ac:56:07:d0:
+ 2b:1f:5f:d0:44:f9:70:e1:44:44:34:ba:fb:3d:54:85:4b:1d:
+ ba:ea:ea:6a:91:0c:08:30:2d:bc:b8:ea:22:c1:16:7b:53:fe:
+ 40:2c:8d:f5:c6:c2:39:e6:11:1d:e2:2f:50:a6:76:9c:fd:b9:
+ fa:d5:10:79:0e:e5:02:87:7d:96:e3:81:05:79:c9:a3:d8:f2:
+ a0:b1:8b:0e:8d:33:73:15:6f:27:88:85:03:8a:c5:7a:77:f4:
+ 3f:7f:b8:65:97:5b:a0:a6:21:48:67:2c:a2:73:a2:ec:d6:6a:
+ bd:d6:f2:e2:b1:5b
+-----BEGIN CERTIFICATE-----
+MIIEUTCCArmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBEMREwDwYDVQQDEwhzb21l
+TmFtZTEQMA4GA1UECxMHcnN5c2xvZzEQMA4GA1UEChMHU29tZU9yZzELMAkGA1UE
+BhMCVVMwIBcNMjMwNzA2MTI1OTI1WhgPMjEyMzA2MTIxMjU5MjVaMIGUMQswCQYD
+VQQGEwJERTEMMAoGA1UECAwDTlJXMRUwEwYDVQQKDAxBZGlzY29uIEdtYkgxEDAO
+BgNVBAsMB3JzeXNsb2cxKTAnBgNVBAMMIHJzeXNsb2cgcmV2b2tlZCBjZXJ0aWZp
+Y2F0ZSB0ZXN0MSMwIQYJKoZIhvcNAQkBFhRhbG9yYmFjaEBhZGlzY29uLmNvbTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/+FF3pnGxnFTzUSZ1bKupD
+wrye0DpeVS9oACsL2tzP99mnG6CjMd2oBxOe3DZ1uDTqFxr2HdszHkU2gK6ck6YC
+Tib4B94czp7nTyXXWSRJXjREVIer4G1aJEEZvzPDpRHWUMD3bS0SA8wLueqyhV2R
+rYTOvpsLwusBl7g63By40kPoll7whOKYGHsVxq8Mu46YliF7zW8Nn4RZv5GoumrJ
+vF9K8xJNM+fcsDjpcdjv0P2eH9Bau6k6kdgep576rBNbo63ohwv0tfioDaexWUAm
+QnoF5DFm+AXR/ZdfrpMK2UVso98y7hF4gy+6Nhd2mIPWCPsxDoF9V4AQPN4NSw0C
+AwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5l
+cmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFCDOolSZzyKaXLvUHrAeQ3Njcqre
+MB8GA1UdIwQYMBaAFLCfZzMsiIiJH0RidJ0l/8AGE13WMA0GCSqGSIb3DQEBCwUA
+A4IBgQAzZSiYlJv1Vw2/AsJnk46OdwObx3pHUymk3aahXioK7RkCgJCzlx8GTJzF
+X2wW+RL73dopiLcskQurU3l6bnYg/vqxmcIrUCZ7zIx1mDWVeVZDkKCVXpgJEE3q
+wBy7wHunipshcIVlg03uZe8Q02OV/VGdbEF7r6+c5zR0oXqGCo7yKgZod3b6/GS8
+KB2LU3rPYg+HqYVUjKVBw2ELz5bB+oGlMWPzyxc3WG7ZMJf7Vy8xY+gmDoJJ4qmb
+7Tl7JE5CjTR0Oty3xdYV6WYoLTzgJkR2ZkoylBHIHxyy3ERpY/cth7WJSkD75BRo
+3Ip2QJM14qyaS7yvxYqKOFTvaQFMkq/AB9AvejyeQKxWB9ArH1/QRPlw4URENLr7
+PVSFSx266upqkQwIMC28uOoiwRZ7U/5ALI31xsI55hEd4i9Qpnac/bn61RB5DuUC
+h32W44EFecmj2PKgsYsOjTNzFW8niIUDisV6d/Q/f7hll1ugpiFIZyyic6Ls1mq9
+1vLisVs=
+-----END CERTIFICATE-----
diff --git a/tests/testsuites/x.509/newcerts/03.pem b/tests/testsuites/x.509/newcerts/03.pem
new file mode 100644
index 0000000..8bc2b8a
--- /dev/null
+++ b/tests/testsuites/x.509/newcerts/03.pem
@@ -0,0 +1,92 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 3 (0x3)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=someName, OU=rsyslog, O=SomeOrg, C=US
+ Validity
+ Not Before: Jul 6 13:38:06 2023 GMT
+ Not After : Jun 12 13:38:06 2123 GMT
+ Subject: C=DE, ST=NRW, O=Adiscon GmbH, OU=rsyslog, CN=rsyslog revoked certificate test/emailAddress=alorbach@adiscon.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:bf:fe:14:5d:e9:9c:6c:67:15:3c:d4:49:9d:5b:
+ 2a:ea:43:c2:bc:9e:d0:3a:5e:55:2f:68:00:2b:0b:
+ da:dc:cf:f7:d9:a7:1b:a0:a3:31:dd:a8:07:13:9e:
+ dc:36:75:b8:34:ea:17:1a:f6:1d:db:33:1e:45:36:
+ 80:ae:9c:93:a6:02:4e:26:f8:07:de:1c:ce:9e:e7:
+ 4f:25:d7:59:24:49:5e:34:44:54:87:ab:e0:6d:5a:
+ 24:41:19:bf:33:c3:a5:11:d6:50:c0:f7:6d:2d:12:
+ 03:cc:0b:b9:ea:b2:85:5d:91:ad:84:ce:be:9b:0b:
+ c2:eb:01:97:b8:3a:dc:1c:b8:d2:43:e8:96:5e:f0:
+ 84:e2:98:18:7b:15:c6:af:0c:bb:8e:98:96:21:7b:
+ cd:6f:0d:9f:84:59:bf:91:a8:ba:6a:c9:bc:5f:4a:
+ f3:12:4d:33:e7:dc:b0:38:e9:71:d8:ef:d0:fd:9e:
+ 1f:d0:5a:bb:a9:3a:91:d8:1e:a7:9e:fa:ac:13:5b:
+ a3:ad:e8:87:0b:f4:b5:f8:a8:0d:a7:b1:59:40:26:
+ 42:7a:05:e4:31:66:f8:05:d1:fd:97:5f:ae:93:0a:
+ d9:45:6c:a3:df:32:ee:11:78:83:2f:ba:36:17:76:
+ 98:83:d6:08:fb:31:0e:81:7d:57:80:10:3c:de:0d:
+ 4b:0d
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 20:CE:A2:54:99:CF:22:9A:5C:BB:D4:1E:B0:1E:43:73:63:72:AA:DE
+ X509v3 Authority Key Identifier:
+ keyid:B0:9F:67:33:2C:88:88:89:1F:44:62:74:9D:25:FF:C0:06:13:5D:D6
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 65:ac:7c:30:d0:01:ce:d7:ff:28:61:6c:8d:99:15:ce:45:22:
+ 8a:39:70:a4:a6:ce:48:94:e3:4b:8c:be:55:c4:66:96:49:49:
+ 4b:e0:4c:95:fd:73:02:54:3a:df:34:2f:96:16:48:ec:c2:23:
+ 3d:ee:b4:5a:dd:a0:c9:eb:85:f4:fd:e8:d5:8f:f3:dc:ce:4a:
+ 88:bb:be:19:81:3f:8b:0f:09:23:46:14:c9:f5:35:5a:cf:25:
+ 7c:92:df:b9:90:5d:ff:4f:21:40:9c:24:7c:0f:1f:3f:62:d1:
+ 7b:cc:40:7d:c6:61:49:f3:84:26:78:ed:87:70:06:9c:93:05:
+ a5:c4:7e:60:3d:d0:4a:2c:e4:d6:e5:33:f8:07:dd:5a:0e:9a:
+ 93:17:50:29:1a:ff:66:61:d9:40:a7:fb:cc:7b:62:b7:9d:29:
+ 1a:2a:3d:7b:93:87:eb:52:4e:00:19:19:3c:4d:73:fc:3d:ed:
+ eb:9d:92:30:bc:b0:ed:51:15:ce:b7:3c:00:09:0c:9d:6d:8b:
+ 2b:c9:f5:66:d4:49:44:58:3d:e7:61:3d:6b:21:05:ff:1d:55:
+ 59:dd:e4:a6:2f:e5:96:82:eb:24:33:2e:47:61:a5:f8:4d:ab:
+ ad:fc:64:f8:8b:9e:0e:62:8c:16:1d:79:18:74:18:9c:a2:19:
+ c3:24:0d:6e:45:63:f9:08:92:7d:44:0b:96:c7:48:84:72:97:
+ 22:23:bf:10:0a:d7:4e:43:8a:db:60:cd:5d:80:5e:71:fa:c2:
+ b6:68:10:ee:cc:29:86:15:d3:d9:93:2a:cc:73:88:be:9f:ad:
+ d0:c5:9c:a4:e4:86:38:e7:41:84:3a:d0:f3:67:1f:2c:40:d7:
+ 04:b1:ea:32:13:49:a5:82:1a:a5:6c:3f:5f:dc:fd:55:14:03:
+ 8b:d7:bd:01:9e:bc:c5:e4:a1:a8:a8:9d:bc:cd:1f:5b:fc:df:
+ 59:b7:0d:aa:47:a0:08:cd:6e:f7:c8:9d:d3:dd:4e:8b:aa:cc:
+ 54:20:a0:2b:63:96
+-----BEGIN CERTIFICATE-----
+MIIEUTCCArmgAwIBAgIBAzANBgkqhkiG9w0BAQsFADBEMREwDwYDVQQDEwhzb21l
+TmFtZTEQMA4GA1UECxMHcnN5c2xvZzEQMA4GA1UEChMHU29tZU9yZzELMAkGA1UE
+BhMCVVMwIBcNMjMwNzA2MTMzODA2WhgPMjEyMzA2MTIxMzM4MDZaMIGUMQswCQYD
+VQQGEwJERTEMMAoGA1UECAwDTlJXMRUwEwYDVQQKDAxBZGlzY29uIEdtYkgxEDAO
+BgNVBAsMB3JzeXNsb2cxKTAnBgNVBAMMIHJzeXNsb2cgcmV2b2tlZCBjZXJ0aWZp
+Y2F0ZSB0ZXN0MSMwIQYJKoZIhvcNAQkBFhRhbG9yYmFjaEBhZGlzY29uLmNvbTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/+FF3pnGxnFTzUSZ1bKupD
+wrye0DpeVS9oACsL2tzP99mnG6CjMd2oBxOe3DZ1uDTqFxr2HdszHkU2gK6ck6YC
+Tib4B94czp7nTyXXWSRJXjREVIer4G1aJEEZvzPDpRHWUMD3bS0SA8wLueqyhV2R
+rYTOvpsLwusBl7g63By40kPoll7whOKYGHsVxq8Mu46YliF7zW8Nn4RZv5GoumrJ
+vF9K8xJNM+fcsDjpcdjv0P2eH9Bau6k6kdgep576rBNbo63ohwv0tfioDaexWUAm
+QnoF5DFm+AXR/ZdfrpMK2UVso98y7hF4gy+6Nhd2mIPWCPsxDoF9V4AQPN4NSw0C
+AwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5l
+cmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFCDOolSZzyKaXLvUHrAeQ3Njcqre
+MB8GA1UdIwQYMBaAFLCfZzMsiIiJH0RidJ0l/8AGE13WMA0GCSqGSIb3DQEBCwUA
+A4IBgQBlrHww0AHO1/8oYWyNmRXORSKKOXCkps5IlONLjL5VxGaWSUlL4EyV/XMC
+VDrfNC+WFkjswiM97rRa3aDJ64X0/ejVj/PczkqIu74ZgT+LDwkjRhTJ9TVazyV8
+kt+5kF3/TyFAnCR8Dx8/YtF7zEB9xmFJ84QmeO2HcAackwWlxH5gPdBKLOTW5TP4
+B91aDpqTF1ApGv9mYdlAp/vMe2K3nSkaKj17k4frUk4AGRk8TXP8Pe3rnZIwvLDt
+URXOtzwACQydbYsryfVm1ElEWD3nYT1rIQX/HVVZ3eSmL+WWguskMy5HYaX4Taut
+/GT4i54OYowWHXkYdBicohnDJA1uRWP5CJJ9RAuWx0iEcpciI78QCtdOQ4rbYM1d
+gF5x+sK2aBDuzCmGFdPZkyrMc4i+n63QxZyk5IY450GEOtDzZx8sQNcEseoyE0ml
+ghqlbD9f3P1VFAOL170BnrzF5KGoqJ28zR9b/N9Ztw2qR6AIzW73yJ3T3U6LqsxU
+IKArY5Y=
+-----END CERTIFICATE-----
diff --git a/tests/testsuites/x.509/newcerts/04.pem b/tests/testsuites/x.509/newcerts/04.pem
new file mode 100644
index 0000000..e92ab86
--- /dev/null
+++ b/tests/testsuites/x.509/newcerts/04.pem
@@ -0,0 +1,102 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 4 (0x4)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=someName, OU=rsyslog, O=SomeOrg, C=US
+ Validity
+ Not Before: Jul 6 13:52:50 2023 GMT
+ Not After : Jun 12 13:52:50 2123 GMT
+ Subject: C=US, ST=CA, O=SomeComp, OU=SomeUnit, CN=rsyslog/emailAddress=alorbach@adiscon.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (3072 bit)
+ Modulus:
+ 00:9d:91:da:d8:2e:3d:9d:ae:85:c3:c5:a7:f6:a4:
+ 66:f8:c8:91:91:b8:70:20:dc:ed:e8:23:ca:53:f7:
+ b8:52:43:f3:a7:eb:fb:df:8a:3b:2c:b0:13:fa:62:
+ d3:a1:53:a4:51:71:1f:68:d9:fd:bc:39:4a:fb:c9:
+ 6a:df:f3:88:84:b0:80:bc:c0:f5:1b:42:11:f6:4c:
+ 1a:d8:2c:62:0b:5d:50:64:30:9a:d3:db:c1:d5:7f:
+ 39:53:e4:bd:e8:1e:04:9d:c9:12:e0:e4:57:29:29:
+ 01:b9:f1:e5:bc:74:a6:e7:4b:61:e6:67:5c:6c:4e:
+ ee:ee:22:0c:1b:14:6d:e8:0c:6f:ee:ee:c3:b8:dd:
+ df:15:ed:7a:96:5b:cc:85:e5:e3:50:c4:ce:2b:bf:
+ b6:37:e6:20:fc:6e:45:7e:09:bd:84:7a:af:07:27:
+ f4:99:23:41:df:36:d8:29:31:a0:96:84:2f:fd:45:
+ 2e:d4:b4:f9:fa:dc:8f:23:c0:e0:06:ad:ad:0a:72:
+ da:f4:3b:a1:cb:d6:a6:3b:ec:46:c4:95:f2:71:a5:
+ ad:08:1f:e7:06:18:0e:db:80:51:96:ba:24:f6:64:
+ 02:6b:d3:f0:76:01:34:3a:72:02:e9:cb:d0:aa:62:
+ 51:0c:8f:83:be:c0:47:99:d2:92:72:ed:53:a5:49:
+ 05:d4:c9:a1:f4:4d:de:12:9d:1a:c8:17:84:f3:a2:
+ 7c:67:47:82:4b:86:1e:73:86:e2:26:26:10:94:a3:
+ 99:9b:08:99:78:9d:3d:33:5d:85:c2:46:65:94:ab:
+ 70:b4:3b:c1:26:8b:11:b6:66:27:88:22:84:03:b5:
+ 08:45:32:8c:81:23:be:62:dc:6f:a0:aa:5e:9f:03:
+ f7:a7:f5:03:70:3c:78:09:d0:84:44:8c:19:af:76:
+ f7:93:fc:af:c6:fd:db:d9:4c:cb:20:79:44:71:cb:
+ e6:55:61:a9:7a:af:0b:a3:a6:ed:e9:a9:11:af:fa:
+ a3:5d:ac:97:e7:ef:2b:b6:a8:37
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ 6E:15:7E:C4:62:2B:92:6D:22:EE:0C:E4:C5:36:29:38:16:62:BE:89
+ X509v3 Authority Key Identifier:
+ keyid:B0:9F:67:33:2C:88:88:89:1F:44:62:74:9D:25:FF:C0:06:13:5D:D6
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 64:b0:45:6b:0c:7c:2d:09:14:8e:78:93:85:ef:d2:31:aa:c3:
+ 59:2e:85:bf:29:e1:46:59:38:d4:fe:ea:c4:c1:83:a7:4a:1b:
+ 92:5e:e8:11:9c:21:48:9d:1e:cc:31:d8:31:00:72:fe:7b:c1:
+ 18:c4:f5:37:f3:3b:0e:1a:f6:3f:19:47:22:c9:87:01:e0:4c:
+ f4:5d:36:0a:87:46:42:fc:6c:ab:26:ff:7d:ca:2c:19:97:ca:
+ 25:fc:70:66:4e:49:86:3e:81:0f:ee:e2:5c:3b:69:07:8b:c2:
+ 52:09:46:d8:67:af:84:54:bb:4f:f3:e0:da:07:c5:64:56:2d:
+ fb:f9:55:13:53:1d:c6:78:63:40:22:23:4f:63:59:37:05:c7:
+ 46:b6:36:53:30:fe:9b:e6:01:0a:54:5b:be:1b:a4:72:c3:27:
+ 1b:c5:21:5d:d3:0c:06:56:d9:df:45:83:e7:06:6d:47:53:72:
+ ea:6c:e7:db:5e:bd:14:47:19:0c:18:13:73:6b:14:dc:29:6c:
+ c0:60:fa:4c:02:74:45:e7:8d:12:bd:1f:cb:77:2c:72:19:ef:
+ e8:85:5c:cf:77:04:b7:d4:08:a8:7e:d1:1d:20:7b:76:27:ca:
+ 8a:5a:2a:a5:e7:15:6c:2d:50:9c:c2:b4:83:45:c2:f7:a5:f0:
+ 6b:d5:45:6b:88:4c:db:00:26:2f:8e:0a:3c:42:4e:0c:64:18:
+ 41:a0:6b:4b:d0:78:89:b4:64:34:5b:76:cb:dd:b9:be:6e:28:
+ 82:ba:6e:11:99:86:88:b6:0d:22:2b:a6:eb:5f:0b:ca:77:5b:
+ 2e:28:b7:f3:96:c3:8c:9d:0d:2b:59:98:d4:20:87:3a:2e:f4:
+ e3:bf:a2:ff:67:4f:3f:1e:ce:ec:59:76:5a:67:81:ba:44:96:
+ 29:af:05:ce:55:02:b4:d6:68:f0:25:61:8c:91:83:03:fd:e4:
+ 2c:06:91:b4:32:d8:5b:47:d6:20:55:44:a6:0c:9b:97:bb:94:
+ 66:25:8c:35:e0:32
+-----BEGIN CERTIFICATE-----
+MIIEszCCAxugAwIBAgIBBDANBgkqhkiG9w0BAQsFADBEMREwDwYDVQQDEwhzb21l
+TmFtZTEQMA4GA1UECxMHcnN5c2xvZzEQMA4GA1UEChMHU29tZU9yZzELMAkGA1UE
+BhMCVVMwIBcNMjMwNzA2MTM1MjUwWhgPMjEyMzA2MTIxMzUyNTBaMHcxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJDQTERMA8GA1UECgwIU29tZUNvbXAxETAPBgNVBAsM
+CFNvbWVVbml0MRAwDgYDVQQDDAdyc3lzbG9nMSMwIQYJKoZIhvcNAQkBFhRhbG9y
+YmFjaEBhZGlzY29uLmNvbTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGB
+AJ2R2tguPZ2uhcPFp/akZvjIkZG4cCDc7egjylP3uFJD86fr+9+KOyywE/pi06FT
+pFFxH2jZ/bw5SvvJat/ziISwgLzA9RtCEfZMGtgsYgtdUGQwmtPbwdV/OVPkvege
+BJ3JEuDkVykpAbnx5bx0pudLYeZnXGxO7u4iDBsUbegMb+7uw7jd3xXtepZbzIXl
+41DEziu/tjfmIPxuRX4JvYR6rwcn9JkjQd822CkxoJaEL/1FLtS0+frcjyPA4Aat
+rQpy2vQ7ocvWpjvsRsSV8nGlrQgf5wYYDtuAUZa6JPZkAmvT8HYBNDpyAunL0Kpi
+UQyPg77AR5nSknLtU6VJBdTJofRN3hKdGsgXhPOifGdHgkuGHnOG4iYmEJSjmZsI
+mXidPTNdhcJGZZSrcLQ7wSaLEbZmJ4gihAO1CEUyjIEjvmLcb6CqXp8D96f1A3A8
+eAnQhESMGa9295P8r8b929lMyyB5RHHL5lVhqXqvC6Om7empEa/6o12sl+fvK7ao
+NwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdl
+bmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUbhV+xGIrkm0i7gzkxTYpOBZi
+vokwHwYDVR0jBBgwFoAUsJ9nMyyIiIkfRGJ0nSX/wAYTXdYwDQYJKoZIhvcNAQEL
+BQADggGBAGSwRWsMfC0JFI54k4Xv0jGqw1kuhb8p4UZZONT+6sTBg6dKG5Je6BGc
+IUidHswx2DEAcv57wRjE9TfzOw4a9j8ZRyLJhwHgTPRdNgqHRkL8bKsm/33KLBmX
+yiX8cGZOSYY+gQ/u4lw7aQeLwlIJRthnr4RUu0/z4NoHxWRWLfv5VRNTHcZ4Y0Ai
+I09jWTcFx0a2NlMw/pvmAQpUW74bpHLDJxvFIV3TDAZW2d9Fg+cGbUdTcups59te
+vRRHGQwYE3NrFNwpbMBg+kwCdEXnjRK9H8t3LHIZ7+iFXM93BLfUCKh+0R0ge3Yn
+yopaKqXnFWwtUJzCtINFwvel8GvVRWuITNsAJi+OCjxCTgxkGEGga0vQeIm0ZDRb
+dsvdub5uKIK6bhGZhoi2DSIrputfC8p3Wy4ot/OWw4ydDStZmNQghzou9OO/ov9n
+Tz8ezuxZdlpngbpElimvBc5VArTWaPAlYYyRgwP95CwGkbQy2FtH1iBVRKYMm5e7
+lGYljDXgMg==
+-----END CERTIFICATE-----
diff --git a/tests/testsuites/x.509/openssl-cmds.sh b/tests/testsuites/x.509/openssl-cmds.sh
new file mode 100644
index 0000000..5bcc382
--- /dev/null
+++ b/tests/testsuites/x.509/openssl-cmds.sh
@@ -0,0 +1,11 @@
+# CREATE KEY
+# openssl genpkey -algorithm RSA -out client-revoked-key.pem
+# CREATE REQEST
+# openssl req -new -key client-revoked-key.pem -out client-revoked.csr
+# CREATE A CERT
+# openssl ca -config openssl.cnf -in client-revoked.csr -out client-revoked.pem -keyfile ca-key.pem -cert ca.pem
+# REVOKE A CERT
+# openssl ca -config openssl.cnf -revoke client-revoked.pem -keyfile ca-key.pem -cert ca.pem
+# CREATE crl.pem
+# openssl ca -config openssl.cnf -gencrl -out crl.pem -keyfile ca-key.pem -cert ca.pem
+
diff --git a/tests/testsuites/x.509/openssl.cnf b/tests/testsuites/x.509/openssl.cnf
new file mode 100644
index 0000000..39eba57
--- /dev/null
+++ b/tests/testsuites/x.509/openssl.cnf
@@ -0,0 +1,41 @@
+[ ca ]
+default_ca = CA_default
+
+[ CA_default ]
+dir = ./
+certs = $dir/certs
+crl_dir = $dir/crl
+database = $dir/index.txt
+new_certs_dir = $dir/newcerts
+
+certificate = $dir/ca.pem
+serial = $dir/serial
+crl = $dir/crl.pem
+private_key = $dir/ca-key.pem
+
+x509_extensions = usr_cert
+name_opt = ca_default
+cert_opt = ca_default
+default_days = 36500
+default_md = sha256
+
+# How long before next CRL, default is 1 but for testing we need no expire, so 100 years is fine.
+default_crl_days = 36500
+
+preserve = no
+policy = policy_match
+
+[ policy_match ]
+countryName = supplied
+stateOrProvinceName = supplied
+organizationName = supplied
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+[ usr_cert ]
+basicConstraints=CA:FALSE
+nsComment="OpenSSL Generated Certificate"
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
diff --git a/tests/testsuites/x.509/serial b/tests/testsuites/x.509/serial
new file mode 100644
index 0000000..eeee65e
--- /dev/null
+++ b/tests/testsuites/x.509/serial
@@ -0,0 +1 @@
+05
diff --git a/tests/testsuites/xlate.lkp_tbl b/tests/testsuites/xlate.lkp_tbl
new file mode 100644
index 0000000..cc98de1
--- /dev/null
+++ b/tests/testsuites/xlate.lkp_tbl
@@ -0,0 +1,5 @@
+{
+ "table":[
+ {"index":" msgnum:00000001:", "value":"bar_old" },
+ {"index":" msgnum:00000000:", "value":"foo_old" }]
+}
diff --git a/tests/testsuites/xlate_array.lkp_tbl b/tests/testsuites/xlate_array.lkp_tbl
new file mode 100644
index 0000000..c2b327b
--- /dev/null
+++ b/tests/testsuites/xlate_array.lkp_tbl
@@ -0,0 +1,6 @@
+{
+ "type" : "array",
+ "table":[
+ {"index": 1, "value":"bar_old" },
+ {"index": 0, "value":"foo_old" }]
+}
diff --git a/tests/testsuites/xlate_array_empty_table.lkp_tbl b/tests/testsuites/xlate_array_empty_table.lkp_tbl
new file mode 100644
index 0000000..e4912d0
--- /dev/null
+++ b/tests/testsuites/xlate_array_empty_table.lkp_tbl
@@ -0,0 +1,6 @@
+{
+ "version": 1,
+ "nomatch": "baz_arr",
+ "type" : "array",
+ "table":[]
+}
diff --git a/tests/testsuites/xlate_array_misuse.lkp_tbl b/tests/testsuites/xlate_array_misuse.lkp_tbl
new file mode 100644
index 0000000..8cc96c0
--- /dev/null
+++ b/tests/testsuites/xlate_array_misuse.lkp_tbl
@@ -0,0 +1,6 @@
+{
+ "type" : "array",
+ "table":[
+ {"index": 3, "value":"bar_old" },
+ {"index": 1, "value":"foo_old" }]
+}
diff --git a/tests/testsuites/xlate_array_more.lkp_tbl b/tests/testsuites/xlate_array_more.lkp_tbl
new file mode 100644
index 0000000..fa93014
--- /dev/null
+++ b/tests/testsuites/xlate_array_more.lkp_tbl
@@ -0,0 +1,7 @@
+{
+ "type" : "array",
+ "table":[
+ {"index": 2, "value":"baz" },
+ {"index": 0, "value":"foo_new" },
+ {"index": 1, "value":"bar_new" }]
+}
diff --git a/tests/testsuites/xlate_array_more_misuse.lkp_tbl b/tests/testsuites/xlate_array_more_misuse.lkp_tbl
new file mode 100644
index 0000000..223d3de
--- /dev/null
+++ b/tests/testsuites/xlate_array_more_misuse.lkp_tbl
@@ -0,0 +1,7 @@
+{
+ "type" : "array",
+ "table":[
+ {"index": 2, "value":"baz" },
+ {"index": 1, "value":"foo_new" },
+ {"index": 1, "value":"bar_new" }]
+}
diff --git a/tests/testsuites/xlate_array_more_with_duplicates_and_nomatch.lkp_tbl b/tests/testsuites/xlate_array_more_with_duplicates_and_nomatch.lkp_tbl
new file mode 100644
index 0000000..d7730e6
--- /dev/null
+++ b/tests/testsuites/xlate_array_more_with_duplicates_and_nomatch.lkp_tbl
@@ -0,0 +1,13 @@
+{
+ "nomatch": "quux",
+ "type" : "array",
+ "table":[
+ {"index": 2, "value": "foo_latest" },
+ {"index": 3, "value": "baz_latest" },
+ {"index": 4, "value": "foo_latest" },
+ {"index": 5, "value": "foo_latest" },
+ {"index": 6, "value": "baz_latest" },
+ {"index": 7, "value": "foo_latest" },
+ {"index": 8, "value": "baz_latest" },
+ {"index": 9, "value": "baz_latest" }]
+}
diff --git a/tests/testsuites/xlate_array_no_index.lkp_tbl b/tests/testsuites/xlate_array_no_index.lkp_tbl
new file mode 100644
index 0000000..30dc209
--- /dev/null
+++ b/tests/testsuites/xlate_array_no_index.lkp_tbl
@@ -0,0 +1,8 @@
+{
+ "version": 1,
+ "nomatch": "baz",
+ "type" : "array",
+ "table":[
+ {"value":"foo" },
+ {"value":"bar" }]
+}
diff --git a/tests/testsuites/xlate_array_no_table.lkp_tbl b/tests/testsuites/xlate_array_no_table.lkp_tbl
new file mode 100644
index 0000000..df47606
--- /dev/null
+++ b/tests/testsuites/xlate_array_no_table.lkp_tbl
@@ -0,0 +1,5 @@
+{
+ "version": 1,
+ "nomatch": "baz",
+ "type" : "array"
+}
diff --git a/tests/testsuites/xlate_array_no_value.lkp_tbl b/tests/testsuites/xlate_array_no_value.lkp_tbl
new file mode 100644
index 0000000..176cafb
--- /dev/null
+++ b/tests/testsuites/xlate_array_no_value.lkp_tbl
@@ -0,0 +1,8 @@
+{
+ "version": 1,
+ "nomatch": "baz",
+ "type" : "array",
+ "table":[
+ {"index":"00000000" },
+ {"index":"00000001" }]
+}
diff --git a/tests/testsuites/xlate_empty_file.lkp_tbl b/tests/testsuites/xlate_empty_file.lkp_tbl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/testsuites/xlate_empty_file.lkp_tbl
diff --git a/tests/testsuites/xlate_incorrect_type.lkp_tbl b/tests/testsuites/xlate_incorrect_type.lkp_tbl
new file mode 100644
index 0000000..0180b6e
--- /dev/null
+++ b/tests/testsuites/xlate_incorrect_type.lkp_tbl
@@ -0,0 +1,8 @@
+{
+ "version": 1,
+ "nomatch": "baz",
+ "type" : "quux",
+ "table":[
+ {"index":" 00000000", "value":"foo" },
+ {"index":" 00000001", "value":"bar" }]
+}
diff --git a/tests/testsuites/xlate_incorrect_version.lkp_tbl b/tests/testsuites/xlate_incorrect_version.lkp_tbl
new file mode 100644
index 0000000..ef2ce7b
--- /dev/null
+++ b/tests/testsuites/xlate_incorrect_version.lkp_tbl
@@ -0,0 +1,8 @@
+{
+ "version": 3,
+ "nomatch": "baz",
+ "type" : "string",
+ "table":[
+ {"index": "00000000", "value":"foo" },
+ {"index": "00000001", "value":"bar" }]
+}
diff --git a/tests/testsuites/xlate_invalid_json.lkp_tbl b/tests/testsuites/xlate_invalid_json.lkp_tbl
new file mode 100644
index 0000000..0d1e247
--- /dev/null
+++ b/tests/testsuites/xlate_invalid_json.lkp_tbl
@@ -0,0 +1,4 @@
+{
+ version": "baz_sparse_arr",
+ "type" : "sparseArray",
+ "table":[]
diff --git a/tests/testsuites/xlate_more.lkp_tbl b/tests/testsuites/xlate_more.lkp_tbl
new file mode 100644
index 0000000..2d3f452
--- /dev/null
+++ b/tests/testsuites/xlate_more.lkp_tbl
@@ -0,0 +1,6 @@
+{
+ "table":[
+ {"index":" msgnum:00000000:", "value":"foo_new" },
+ {"index":" msgnum:00000001:", "value":"bar_new" },
+ {"index":" msgnum:00000002:", "value":"baz" }]
+}
diff --git a/tests/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl b/tests/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl
new file mode 100644
index 0000000..ac50664
--- /dev/null
+++ b/tests/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl
@@ -0,0 +1,12 @@
+{
+ "nomatch": "quux",
+ "table":[
+ {"index":" msgnum:00000000:", "value":"foo_latest" },
+ {"index":" msgnum:00000002:", "value":"baz_latest" },
+ {"index":" msgnum:00000003:", "value":"foo_latest" },
+ {"index":" msgnum:00000004:", "value":"foo_latest" },
+ {"index":" msgnum:00000005:", "value":"baz_latest" },
+ {"index":" msgnum:00000006:", "value":"foo_latest" },
+ {"index":" msgnum:00000007:", "value":"baz_latest" },
+ {"index":" msgnum:00000008:", "value":"baz_latest" }]
+}
diff --git a/tests/testsuites/xlate_sparseArray_empty_table.lkp_tbl b/tests/testsuites/xlate_sparseArray_empty_table.lkp_tbl
new file mode 100644
index 0000000..f33c7d7
--- /dev/null
+++ b/tests/testsuites/xlate_sparseArray_empty_table.lkp_tbl
@@ -0,0 +1,6 @@
+{
+ "version": 1,
+ "nomatch": "baz_sparse_arr",
+ "type" : "sparseArray",
+ "table":[]
+}
diff --git a/tests/testsuites/xlate_sparseArray_no_index.lkp_tbl b/tests/testsuites/xlate_sparseArray_no_index.lkp_tbl
new file mode 100644
index 0000000..29ba48c
--- /dev/null
+++ b/tests/testsuites/xlate_sparseArray_no_index.lkp_tbl
@@ -0,0 +1,8 @@
+{
+ "version": 1,
+ "nomatch": "baz",
+ "type" : "sparseArray",
+ "table":[
+ {"value":"foo" },
+ {"value":"bar" }]
+}
diff --git a/tests/testsuites/xlate_sparseArray_no_table.lkp_tbl b/tests/testsuites/xlate_sparseArray_no_table.lkp_tbl
new file mode 100644
index 0000000..45fc9a9
--- /dev/null
+++ b/tests/testsuites/xlate_sparseArray_no_table.lkp_tbl
@@ -0,0 +1,5 @@
+{
+ "version": 1,
+ "nomatch": "baz",
+ "type" : "sparseArray"
+}
diff --git a/tests/testsuites/xlate_sparseArray_no_value.lkp_tbl b/tests/testsuites/xlate_sparseArray_no_value.lkp_tbl
new file mode 100644
index 0000000..e5c65ee
--- /dev/null
+++ b/tests/testsuites/xlate_sparseArray_no_value.lkp_tbl
@@ -0,0 +1,8 @@
+{
+ "version": 1,
+ "nomatch": "baz",
+ "type" : "sparseArray",
+ "table":[
+ {"index":"00000000" },
+ {"index":"00000001" }]
+}
diff --git a/tests/testsuites/xlate_sparse_array.lkp_tbl b/tests/testsuites/xlate_sparse_array.lkp_tbl
new file mode 100644
index 0000000..84523f1
--- /dev/null
+++ b/tests/testsuites/xlate_sparse_array.lkp_tbl
@@ -0,0 +1,6 @@
+{
+ "type" : "sparseArray",
+ "table":[
+ {"index": 3, "value":"bar_old" },
+ {"index": 1, "value":"foo_old" }]
+}
diff --git a/tests/testsuites/xlate_sparse_array_more.lkp_tbl b/tests/testsuites/xlate_sparse_array_more.lkp_tbl
new file mode 100644
index 0000000..bf52153
--- /dev/null
+++ b/tests/testsuites/xlate_sparse_array_more.lkp_tbl
@@ -0,0 +1,7 @@
+{
+ "type" : "sparseArray",
+ "table":[
+ {"index": 4, "value":"baz" },
+ {"index": 0, "value":"foo_new" },
+ {"index": 2, "value":"bar_new" }]
+}
diff --git a/tests/testsuites/xlate_sparse_array_more_with_duplicates_and_nomatch.lkp_tbl b/tests/testsuites/xlate_sparse_array_more_with_duplicates_and_nomatch.lkp_tbl
new file mode 100644
index 0000000..0dc9169
--- /dev/null
+++ b/tests/testsuites/xlate_sparse_array_more_with_duplicates_and_nomatch.lkp_tbl
@@ -0,0 +1,12 @@
+{
+ "nomatch": "quux",
+ "type" : "sparseArray",
+ "table":[
+ {"index": 2, "value": "foo_latest" },
+ {"index": 3, "value": "baz_latest" },
+ {"index": 4, "value": "foo_latest" },
+ {"index": 5, "value": "foo_latest" },
+ {"index": 8, "value": "baz_latest" },
+ {"index": 10, "value": "baz_latest" },
+ {"index": 12, "value": "foo_latest" }]
+}
diff --git a/tests/testsuites/xlate_string_empty_table.lkp_tbl b/tests/testsuites/xlate_string_empty_table.lkp_tbl
new file mode 100644
index 0000000..81358da
--- /dev/null
+++ b/tests/testsuites/xlate_string_empty_table.lkp_tbl
@@ -0,0 +1,6 @@
+{
+ "version": 1,
+ "nomatch": "baz_str",
+ "type" : "string",
+ "table":[]
+}
diff --git a/tests/testsuites/xlate_string_no_index.lkp_tbl b/tests/testsuites/xlate_string_no_index.lkp_tbl
new file mode 100644
index 0000000..c5a0eec
--- /dev/null
+++ b/tests/testsuites/xlate_string_no_index.lkp_tbl
@@ -0,0 +1,8 @@
+{
+ "version": 1,
+ "nomatch": "baz",
+ "type" : "string",
+ "table":[
+ {"value":"foo" },
+ {"value":"bar" }]
+}
diff --git a/tests/testsuites/xlate_string_no_table.lkp_tbl b/tests/testsuites/xlate_string_no_table.lkp_tbl
new file mode 100644
index 0000000..d941488
--- /dev/null
+++ b/tests/testsuites/xlate_string_no_table.lkp_tbl
@@ -0,0 +1,5 @@
+{
+ "version": 1,
+ "nomatch": "baz",
+ "type" : "string"
+}
diff --git a/tests/testsuites/xlate_string_no_value.lkp_tbl b/tests/testsuites/xlate_string_no_value.lkp_tbl
new file mode 100644
index 0000000..d2280f2
--- /dev/null
+++ b/tests/testsuites/xlate_string_no_value.lkp_tbl
@@ -0,0 +1,8 @@
+{
+ "version": 1,
+ "nomatch": "baz",
+ "type" : "string",
+ "table":[
+ {"index":"00000000" },
+ {"index":"00000001" }]
+}
diff --git a/tests/testsuites/zoo.cfg b/tests/testsuites/zoo.cfg
new file mode 100644
index 0000000..b3a3cac
--- /dev/null
+++ b/tests/testsuites/zoo.cfg
@@ -0,0 +1,5 @@
+tickTime=1000
+initLimit=5
+syncLimit=2
+dataDir=zk_data_dir
+clientPort=22181
diff --git a/tests/testsuites/zoo.dep_wrk1.cfg b/tests/testsuites/zoo.dep_wrk1.cfg
new file mode 100644
index 0000000..b3a3cac
--- /dev/null
+++ b/tests/testsuites/zoo.dep_wrk1.cfg
@@ -0,0 +1,5 @@
+tickTime=1000
+initLimit=5
+syncLimit=2
+dataDir=zk_data_dir
+clientPort=22181
diff --git a/tests/testsuites/zoo.dep_wrk2.cfg b/tests/testsuites/zoo.dep_wrk2.cfg
new file mode 100644
index 0000000..a97d0ec
--- /dev/null
+++ b/tests/testsuites/zoo.dep_wrk2.cfg
@@ -0,0 +1,5 @@
+tickTime=1000
+initLimit=5
+syncLimit=2
+dataDir=zk_data_dir
+clientPort=22182
diff --git a/tests/testsuites/zoo.dep_wrk3.cfg b/tests/testsuites/zoo.dep_wrk3.cfg
new file mode 100644
index 0000000..94d9667
--- /dev/null
+++ b/tests/testsuites/zoo.dep_wrk3.cfg
@@ -0,0 +1,5 @@
+tickTime=1000
+initLimit=5
+syncLimit=2
+dataDir=zk_data_dir
+clientPort=22183
diff --git a/tests/threadingmq.sh b/tests/threadingmq.sh
new file mode 100755
index 0000000..c3eaed7
--- /dev/null
+++ b/tests/threadingmq.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# we send 100,000 messages in the hopes that his puts at least a little bit
+# of pressure on the threading subsystem. To really prove it, we would need to
+# push messages for several minutes, but that takes too long during the
+# automated tests (hint: do this manually after suspect changes). Thankfully,
+# in practice many threading bugs result in an abort rather quickly and these
+# should be covered by this test here.
+# rgerhards, 2009-06-26
+echo \[threadingmq.sh\]: main queue concurrency
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MainMsgQueueTimeoutShutdown 1
+#$MainMsgQueueTimeoutShutdown 100000
+
+$MainMsgQueueWorkerThreadMinimumMessages 10
+$MainMsgQueueWorkerThreads 5
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+# write quickly to the output file:
+$OMFileFlushOnTXEnd off
+$OMFileIOBufferSize 256k
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+injectmsg 0 100000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+# we give an extra seconds for things to settle, especially
+# important on slower test machines
+./msleep 5000
+wait_shutdown
+seq_check 0 99999
+exit_test
diff --git a/tests/threadingmqaq.sh b/tests/threadingmqaq.sh
new file mode 100755
index 0000000..e657011
--- /dev/null
+++ b/tests/threadingmqaq.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# we send 100,000 messages in the hopes that his puts at least a little bit
+# of pressure on the threading subsystem. To really prove it, we would need to
+# push messages for several minutes, but that takes too long during the
+# automated tests (hint: do this manually after suspect changes). Thankfully,
+# in practice many threading bugs result in an abort rather quickly and these
+# should be covered by this test here.
+# rgerhards, 2009-06-26
+
+uname
+if [ $(uname) = "SunOS" ] ; then
+ echo "This test currently does not work on all flavors of Solaris."
+ exit 77
+fi
+
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$MainMsgQueueTimeoutShutdown 10000
+
+$MainMsgQueueWorkerThreadMinimumMessages 10
+$MainMsgQueueWorkerThreads 5
+
+$template outfmt,"%msg:F,58:2%\n"
+template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names!
+# write quickly to the output file:
+$OMFileFlushOnTXEnd off
+$OMFileIOBufferSize 256k
+# This time, also run the action queue detached
+$ActionQueueWorkerThreadMinimumMessages 10
+$ActionQueueWorkerThreads 5
+$ActionQueueTimeoutEnqueue 10000
+$ActionQueueType LinkedList
+:msg, contains, "msgnum:" ?dynfile;outfmt
+'
+startup
+#tcpflood -c2 -m100000
+#shutdown_when_empty # shut down rsyslogd when done processing messages
+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
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown
+seq_check 0 99999
+exit_test
diff --git a/tests/timegenerated-dateordinal-invld.sh b/tests/timegenerated-dateordinal-invld.sh
new file mode 100755
index 0000000..e9ea339
--- /dev/null
+++ b/tests/timegenerated-dateordinal-invld.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# addd 2016-03-02 by RGerhards, released under ASL 2.0
+# the key point of this test is that we do not abort and
+# instead provide the defined return value (0)
+# requires faketime
+echo \[timegenerated-dateordinal-invld\]: check invalid dates with ordinal format
+. ${srcdir:=.}/diag.sh init
+
+. $srcdir/faketime_common.sh
+
+export TZ=UTC+00:00
+export EXPECTED="001" # same for all tests
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%timegenerated:::date-ordinal%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+
+echo "***SUBTEST: check 1800-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='1800-01-01 00:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+cmp_exact
+
+
+echo "***SUBTEST: check 1960-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='1960-01-01 00:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+cmp_exact
+
+
+echo "***SUBTEST: check 2101-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2101-01-01 00:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+cmp_exact
+
+
+echo "***SUBTEST: check 2500-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2500-01-01 00:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+cmp_exact
+
+exit_test
diff --git a/tests/timegenerated-dateordinal.sh b/tests/timegenerated-dateordinal.sh
new file mode 100755
index 0000000..41bccbd
--- /dev/null
+++ b/tests/timegenerated-dateordinal.sh
@@ -0,0 +1,168 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# addd 2016-03-02 by RGerhards, released under ASL 2.0
+# Note: we run several subtests here in order to save us
+# from creating additional tests
+# requires faketime
+echo \[timegenerated-dateordinal\]: check valid dates with ordinal format
+. ${srcdir:=.}/diag.sh init
+
+. $srcdir/faketime_common.sh
+
+export TZ=UTC+00:00
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%timegenerated:::date-ordinal%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+
+echo "***SUBTEST: check 1970-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='1970-01-01 00:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="001"
+cmp_exact
+
+
+echo "***SUBTEST: check 2000-03-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2000-03-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="061"
+cmp_exact
+
+
+echo "***SUBTEST: check 2016-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2016-01-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="001"
+cmp_exact
+
+
+echo "***SUBTEST: check 2016-02-29"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2016-02-29 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="060"
+cmp_exact
+
+
+echo "***SUBTEST: check 2016-03-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2016-03-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="061"
+cmp_exact
+
+
+echo "***SUBTEST: check 2016-03-03"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2016-03-03 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="063"
+cmp_exact
+
+
+echo "***SUBTEST: check 2016-12-31"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2016-12-31 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="366"
+cmp_exact
+
+
+echo "***SUBTEST: check 2017-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2017-01-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="001"
+cmp_exact
+
+
+echo "***SUBTEST: check 2020-03-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2020-03-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="061"
+cmp_exact
+
+
+echo "***SUBTEST: check 2038-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2038-01-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="001"
+cmp_exact
+
+
+rsyslog_testbench_require_y2k38_support
+
+
+echo "***SUBTEST: check 2038-12-31"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2038-12-31 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="365"
+cmp_exact
+
+
+echo "***SUBTEST: check 2040-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2040-01-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="001"
+cmp_exact
+
+
+echo "***SUBTEST: check 2040-12-31"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2040-12-31 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="366"
+cmp_exact
+
+
+echo "***SUBTEST: check 2100-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2100-01-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="001"
+cmp_exact
+
+exit_test
diff --git a/tests/timegenerated-utc-legacy.sh b/tests/timegenerated-utc-legacy.sh
new file mode 100755
index 0000000..fb77a43
--- /dev/null
+++ b/tests/timegenerated-utc-legacy.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# added 2016-03-22 by RGerhards, released under ASL 2.0
+#
+# NOTE: faketime does NOT properly support subseconds,
+# so we must ensure we do not use them. Actually, what we
+# see is uninitialized data value in tv_usec, which goes
+# away as soon as we do not run under faketime control.
+# FOR THE SAME REASON, there is NO VALGRIND EQUIVALENT
+# of this test, as valgrind would abort with reports
+# of faketime.
+#
+# IMPORTANT: we use legacy style for the template to ensure
+# that subseconds works properly for this as well. This is
+# a frequent use case.
+#
+. ${srcdir:=.}/diag.sh init
+. $srcdir/faketime_common.sh
+export TZ=TEST+02:00
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%timegenerated:::date-utc%\n"
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+
+echo "***SUBTEST: check 2016-03-01"
+FAKETIME='2016-03-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="Mar 1 14:00:00"
+cmp_exact
+exit_test
diff --git a/tests/timegenerated-utc.sh b/tests/timegenerated-utc.sh
new file mode 100755
index 0000000..6134911
--- /dev/null
+++ b/tests/timegenerated-utc.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# addd 2016-03-22 by RGerhards, released under ASL 2.0
+
+# NOTE: faketime does NOT properly support subseconds,
+# so we must ensure we do not use them. Actually, what we
+# see is uninitialized data value in tv_usec, which goes
+# away as soon as we do not run under faketime control.
+# FOR THE SAME REASON, there is NO VALGRIND EQUIVALENT
+# of this test, as valgrind would abort with reports
+# of faketime.
+. ${srcdir:=.}/diag.sh init
+. $srcdir/faketime_common.sh
+
+export TZ=TEST+02:00
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="list") {
+ property(name="timegenerated" date.inUTC="on")
+ constant(value="\n")
+}
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+echo "***SUBTEST: check 2016-03-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2016-03-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "Mar 1 14:00:00" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi;
+
+exit_test
diff --git a/tests/timegenerated-uxtimestamp-invld.sh b/tests/timegenerated-uxtimestamp-invld.sh
new file mode 100755
index 0000000..7c07d6e
--- /dev/null
+++ b/tests/timegenerated-uxtimestamp-invld.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# addd 2016-03-02 by RGerhards, released under ASL 2.0
+# the key point of this test is that we do not abort and
+# instead provide the defined return value (0)
+# requires faketime
+echo \[timegenerated-uxtimestamp-invld\]: check invalid dates with uxtimestamp format
+. ${srcdir:=.}/diag.sh init
+
+. $srcdir/faketime_common.sh
+
+export TZ=UTC+00:00
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%timegenerated:::date-unixtimestamp%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+
+
+echo "***SUBTEST: check 1800-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='1800-01-01 00:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="0"
+cmp_exact
+
+
+echo "***SUBTEST: check 1960-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='1960-01-01 00:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="0"
+cmp_exact
+
+
+echo "***SUBTEST: check 2101-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2101-01-01 00:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="0"
+cmp_exact
+
+
+echo "***SUBTEST: check 2500-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2500-01-01 00:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="0"
+cmp_exact
+
+exit_test
diff --git a/tests/timegenerated-uxtimestamp.sh b/tests/timegenerated-uxtimestamp.sh
new file mode 100755
index 0000000..5fda9bf
--- /dev/null
+++ b/tests/timegenerated-uxtimestamp.sh
@@ -0,0 +1,207 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# addd 2016-03-02 by RGerhards, released under ASL 2.0
+# Note: we run several subtests here in order to save us
+# from creating additional tests
+# requires faketime
+echo \[timegenerated-uxtimestamp\]: check valid dates with uxtimestamp format
+. ${srcdir:=.}/diag.sh init
+
+. $srcdir/faketime_common.sh
+
+export TZ=UTC+00:00
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%timegenerated:::date-unixtimestamp%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+
+
+echo "***SUBTEST: check 1970-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='1970-01-01 00:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "0" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ exit 1
+fi;
+
+
+echo "***SUBTEST: check 2000-03-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2000-03-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "951912000" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ exit 1
+fi;
+
+
+echo "***SUBTEST: check 2016-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2016-01-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "1451649600" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ exit 1
+fi;
+
+
+echo "***SUBTEST: check 2016-02-29"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2016-02-29 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "1456747200" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ exit 1
+fi;
+
+
+echo "***SUBTEST: check 2016-03-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2016-03-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "1456833600" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ exit 1
+fi;
+
+
+echo "***SUBTEST: check 2016-03-03"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2016-03-03 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "1457006400" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ exit 1
+fi;
+
+
+echo "***SUBTEST: check 2016-12-31"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2016-12-31 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "1483185600" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ exit 1
+fi;
+
+
+echo "***SUBTEST: check 2017-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2017-01-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "1483272000" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ exit 1
+fi;
+
+
+echo "***SUBTEST: check 2020-03-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2020-03-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "1583064000" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ exit 1
+fi;
+
+
+echo "***SUBTEST: check 2038-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2038-01-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "2145960000" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ exit 1
+fi;
+
+rsyslog_testbench_require_y2k38_support
+
+echo "***SUBTEST: check 2040-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2040-01-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "2209032000" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ exit 1
+fi;
+
+
+echo "***SUBTEST: check 2100-01-01"
+rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest
+FAKETIME='2100-01-01 12:00:00' startup
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+echo "4102488000" | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:"
+ date -d @$(pwd $RSYSLOG_OUT_LOG)
+ cat $RSYSLOG_OUT_LOG
+ exit 1
+fi;
+
+
+exit_test
diff --git a/tests/timegenerated-ymd.sh b/tests/timegenerated-ymd.sh
new file mode 100755
index 0000000..48779ed
--- /dev/null
+++ b/tests/timegenerated-ymd.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# test many concurrent tcp connections
+# addd 2016-02-23 by RGerhards, released under ASL 2.0
+# requires faketime
+echo \[timegenerated-ymd\]: check customized format \(Y-m-d\)
+. ${srcdir:=.}/diag.sh init
+
+. $srcdir/faketime_common.sh
+
+export TZ=TEST-02:00
+
+generate_conf
+add_conf '
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string"
+ string="%timegenerated:::date-year%-%timegenerated:::date-month%-%timegenerated:::date-day%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file=`echo $RSYSLOG_OUT_LOG`)
+'
+FAKETIME='2016-01-01 01:00:00' startup
+# what we send actually is irrelevant, as we just use system properties.
+# but we need to send one message in order to gain output!
+tcpflood -m1
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="2016-01-01"
+cmp_exact
+
+
+exit_test
diff --git a/tests/timereported-utc-legacy.sh b/tests/timereported-utc-legacy.sh
new file mode 100755
index 0000000..5b85eb5
--- /dev/null
+++ b/tests/timereported-utc-legacy.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# addd 2016-03-22 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string"
+ string="%timereported:::date-rfc3339,date-utc%\n")
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+
+echo "*** SUBTEST 2003 ****"
+startup
+injectmsg_literal "<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000"
+injectmsg_literal "<165>1 2016-03-01T12:00:00-02:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000"
+injectmsg_literal "<165>1 2016-03-01T12:00:00Z 192.0.2.1 tcpflood 8710 - - msgnum:0000000"
+shutdown_when_empty
+wait_shutdown
+export EXPECTED="2003-08-24T12:14:15.000003+00:00
+2016-03-01T14:00:00.000000+00:00
+2016-03-01T12:00:00.000000+00:00"
+cmp_exact
+
+exit_test
diff --git a/tests/timereported-utc-vg.sh b/tests/timereported-utc-vg.sh
new file mode 100755
index 0000000..9392f0b
--- /dev/null
+++ b/tests/timereported-utc-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# addd 2016-03-22 by RGerhards, released under ASL 2.0
+export USE_VALGRIND="YES"
+source ${srcdir:-.}/timereported-utc.sh
diff --git a/tests/timereported-utc.sh b/tests/timereported-utc.sh
new file mode 100755
index 0000000..4c8a189
--- /dev/null
+++ b/tests/timereported-utc.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# addd 2016-03-22 by RGerhards, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=3
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+template(name="outfmt" type="list") {
+ property(name="timereported" dateformat="rfc3339" date.inUTC="on")
+ constant(value="\n")
+}
+:msg, contains, "msgnum:" action(type="omfile" template="outfmt"
+ file="'$RSYSLOG_OUT_LOG'")
+'
+
+startup
+injectmsg_literal "<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000"
+injectmsg_literal "<165>1 2016-03-01T12:00:00-02:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000"
+injectmsg_literal "<165>1 2016-03-01T12:00:00Z 192.0.2.1 tcpflood 8710 - - msgnum:0000000"
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED="2003-08-24T12:14:15.000003+00:00
+2016-03-01T14:00:00.000000+00:00
+2016-03-01T12:00:00.000000+00:00"
+cmp_exact
+exit_test
diff --git a/tests/timestamp-3164.sh b/tests/timestamp-3164.sh
new file mode 100755
index 0000000..49a6c3a
--- /dev/null
+++ b/tests/timestamp-3164.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# add 2018-06-25 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%timestamp:::date-rfc3164%\n")
+
+:syslogtag, contains, "TAG" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+
+
+'
+startup
+injectmsg_literal "<167>Jan 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Feb 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Mar 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Apr 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>May 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Jun 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Jul 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Aug 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Sep 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Oct 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Nov 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Dec 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Jan 6 16:57:54 172.20.245.8 TAG: MSG"
+injectmsg_literal "<167>Jan 16 16:57:54 172.20.245.8 TAG: MSG"
+shutdown_when_empty
+wait_shutdown
+
+echo 'Jan 6 16:57:54
+Feb 6 16:57:54
+Mar 6 16:57:54
+Apr 6 16:57:54
+May 6 16:57:54
+Jun 6 16:57:54
+Jul 6 16:57:54
+Aug 6 16:57:54
+Sep 6 16:57:54
+Oct 6 16:57:54
+Nov 6 16:57:54
+Dec 6 16:57:54
+Jan 6 16:57:54
+Jan 16 16:57:54' | cmp - $RSYSLOG_OUT_LOG
+if [ ! $? -eq 0 ]; then
+ echo "invalid response generated, $RSYSLOG_OUT_LOG is:"
+ cat $RSYSLOG_OUT_LOG
+ error_exit 1
+fi;
+
+exit_test
diff --git a/tests/timestamp-3339.sh b/tests/timestamp-3339.sh
new file mode 100755
index 0000000..2eb42be
--- /dev/null
+++ b/tests/timestamp-3339.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# add 2018-06-25 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%timestamp:::date-rfc3339%\n")
+
+:syslogtag, contains, "su" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+
+'
+startup
+injectmsg_literal "<34>1 2003-11-11T22:14:15.003Z mymachine.example.com su - ID47 - MSG"
+injectmsg_literal "<34>1 2003-01-11T22:14:15.003Z mymachine.example.com su - ID47 - MSG"
+injectmsg_literal "<34>1 2003-11-01T22:04:15.003Z mymachine.example.com su - ID47 - MSG"
+injectmsg_literal "<34>1 2003-11-11T02:14:15.003Z mymachine.example.com su - ID47 - MSG"
+injectmsg_literal "<34>1 2003-11-11T22:04:05.003Z mymachine.example.com su - ID47 - MSG"
+injectmsg_literal "<34>1 2003-11-11T22:04:05.003+02:00 mymachine.example.com su - ID47 - MSG"
+injectmsg_literal "<34>1 2003-11-11T22:04:05.003+01:30 mymachine.example.com su - ID47 - MSG"
+injectmsg_literal "<34>1 2003-11-11T22:04:05.123456+01:30 mymachine.example.com su - ID47 - MSG"
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='2003-11-11T22:14:15.003Z
+2003-01-11T22:14:15.003Z
+2003-11-01T22:04:15.003Z
+2003-11-11T02:14:15.003Z
+2003-11-11T22:04:05.003Z
+2003-11-11T22:04:05.003+02:00
+2003-11-11T22:04:05.003+01:30
+2003-11-11T22:04:05.123456+01:30'
+cmp_exact
+exit_test
diff --git a/tests/timestamp-isoweek.sh b/tests/timestamp-isoweek.sh
new file mode 100755
index 0000000..43c8fd9
--- /dev/null
+++ b/tests/timestamp-isoweek.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# add 2021-12-27 by Mattia Barbon, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%timestamp:::date-iso-week-year%/%timestamp:::date-iso-week%\n")
+
+:syslogtag, contains, "su" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+
+
+'
+startup
+injectmsg_literal "<34>1 1971-01-01T12:34:56.003Z mymachine.example.com su - ID47 - MSG"
+injectmsg_literal "<34>1 2021-12-02T12:34:56.123456Z mymachine.example.com su - ID47 - MSG"
+injectmsg_literal "<34>1 2099-12-31T12:34:56Z mymachine.example.com su - ID47 - MSG"
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='1970/53
+2021/48
+2099/53'
+cmp_exact
+exit_test
diff --git a/tests/timestamp-mysql.sh b/tests/timestamp-mysql.sh
new file mode 100755
index 0000000..57766e7
--- /dev/null
+++ b/tests/timestamp-mysql.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# add 2018-06-25 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%timestamp:::date-mysql%\n")
+
+:syslogtag, contains, "su" action(type="omfile" file="'$RSYSLOG_OUT_LOG'"
+ template="outfmt")
+
+'
+startup
+injectmsg_literal "<34>1 2003-01-23T12:34:56.003Z mymachine.example.com su - ID47 - MSG\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='20030123123456'
+cmp_exact
+exit_test
diff --git a/tests/timestamp-pgsql.sh b/tests/timestamp-pgsql.sh
new file mode 100755
index 0000000..f92a197
--- /dev/null
+++ b/tests/timestamp-pgsql.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+# add 2018-06-27 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%timestamp:::date-pgsql%\n")
+
+:syslogtag, contains, "su" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+
+
+'
+startup
+injectmsg_literal "<34>1 2003-01-23T12:34:56.003Z mymachine.example.com su - ID47 - MSG\""
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='2003-01-23 12:34:56'
+cmp_exact
+exit_test
diff --git a/tests/timestamp-subseconds.sh b/tests/timestamp-subseconds.sh
new file mode 100755
index 0000000..c114900
--- /dev/null
+++ b/tests/timestamp-subseconds.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# add 2018-06-25 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+template(name="outfmt" type="string" string="%timestamp:::date-subseconds%\n")
+
+:syslogtag, contains, "su" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`
+ template="outfmt")
+
+
+'
+startup
+injectmsg_literal "<34>1 2003-01-23T12:34:56.003Z mymachine.example.com su - ID47 - MSG"
+injectmsg_literal "<34>1 2003-01-23T12:34:56.123456Z mymachine.example.com su - ID47 - MSG"
+injectmsg_literal "<34>1 2003-01-23T12:34:56Z mymachine.example.com su - ID47 - MSG"
+shutdown_when_empty
+wait_shutdown
+
+export EXPECTED='003
+123456
+0'
+cmp_exact
+exit_test
diff --git a/tests/tls-certs/ca-fail.pem b/tests/tls-certs/ca-fail.pem
new file mode 100644
index 0000000..7318f36
--- /dev/null
+++ b/tests/tls-certs/ca-fail.pem
@@ -0,0 +1,3 @@
+-----BEGIN CERTIFICATE-----
+this is an invalid cert
+-----END CERTIFICATE-----
diff --git a/tests/tls-certs/ca-key.pem b/tests/tls-certs/ca-key.pem
new file mode 100644
index 0000000..829c063
--- /dev/null
+++ b/tests/tls-certs/ca-key.pem
@@ -0,0 +1,190 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:c7:03:50:9e:34:8d:f4:7a:7e:ce:28:62:7f:a5:6c
+ 8d:48:7f:6b:9f:0f:33:e9:e8:03:c5:d4:e3:b4:e2:22
+ 72:10:36:fc:b5:4f:68:66:58:79:c2:34:18:7f:d4:b6
+ 44:60:33:af:64:16:ea:3a:75:16:96:be:bd:32:a7:e5
+ cf:7c:69:40:70:57:0f:83:a7:18:28:4a:18:c9:bd:7c
+ 1e:c4:d1:7b:2b:80:71:d0:5c:61:06:20:d9:97:66:02
+ ab:6a:78:70:2a:71:be:f0:48:40:7c:5e:e5:cb:74:3d
+ 85:96:c7:28:dc:66:93:df:31:4d:bf:bb:7b:40:50:d6
+ d5:bd:ad:4f:ff:76:c3:e4:06:b4:8d:53:af:92:c2:31
+ 56:c8:49:11:92:43:38:42:bf:6f:65:dd:4b:56:b7:84
+ 8a:03:d5:bc:ca:18:39:cc:c2:64:30:4c:5a:50:95:6d
+ 56:24:45:94:01:73:2a:b5:15:28:5a:99:f2:cb:33:cb
+ 6c:97:21:c4:cb:b2:42:49:73:98:9f:f2:8e:5c:a5:60
+ ab:6d:c5:d2:6f:94:ec:1c:0f:b8:14:73:81:ea:8b:b4
+ cf:bf:ec:dc:bc:18:8e:87:f4:e7:a6:72:8b:18:f4:2c
+ ce:2c:4d:82:04:b6:d0:ee:2c:44:51:bd:84:c8:86:d2
+ e1:94:0d:81:59:f0:1f:b9:6f:5b:1a:ea:20:d0:2f:71
+ 1a:9b:7d:f6:f9:e2:1c:99:4a:98:c9:ac:ab:3e:61:10
+ 32:d8:ce:25:04:7e:3e:6a:cd:2c:4a:31:c0:36:54:27
+ 8e:d4:38:1a:8d:27:9d:87:5d:d5:37:fb:16:53:29:39
+ 68:a0:3b:d6:2e:34:0a:7a:78:a0:af:ee:cd:e6:16:ee
+ f5:a5:fe:db:42:10:57:3a:c7:ca:73:78:c7:68:06:3b
+ f5:25:df:61:0b:46:76:52:0b:6d:0b:f2:a7:31:32:97
+ df:2e:8d:47:53:d5:16:30:d0:dc:c2:00:ec:18:71:8f
+ 9d:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 25:31:61:67:af:ba:b7:ee:0c:b4:ca:a7:5d:e3:b4:9d
+ d2:e6:bd:5e:44:a1:17:1d:dd:56:a3:aa:ca:ab:58:74
+ a8:c3:1e:07:64:87:c6:58:d2:a8:90:c3:e3:60:05:90
+ 51:ca:57:05:05:a3:50:b9:81:37:3a:fe:70:f1:1f:e9
+ de:fe:6c:a4:92:20:bc:22:06:49:c1:4f:50:a4:b1:05
+ af:12:d7:4a:11:ff:33:49:90:78:6c:bb:3d:a8:3a:e7
+ 7e:46:73:ef:fa:c2:0c:75:f4:57:4a:04:f8:39:09:26
+ 66:3f:62:4b:8e:80:24:3e:3a:a1:92:90:3e:3c:dd:69
+ a4:c1:37:2a:2f:2f:fc:f5:a3:d8:a5:c3:32:52:48:96
+ 47:68:20:78:8d:47:7e:71:f8:87:b9:0b:d3:71:08:bc
+ 22:6b:57:95:0d:61:ff:fa:74:6e:f2:56:0e:a9:5e:7d
+ b2:d9:ae:07:77:56:8b:f1:20:51:8e:63:e9:c6:0c:46
+ 32:3f:da:3d:97:2a:7d:8d:44:42:63:ad:55:a8:79:13
+ 41:35:e0:85:55:c0:30:94:1d:95:f0:e9:55:4e:c0:cf
+ ce:39:f3:18:38:e2:bb:d5:b3:08:c2:eb:cb:20:37:08
+ 58:0d:52:bc:ee:45:bc:56:21:31:3c:d3:ee:02:cb:71
+ ea:59:d7:d5:c2:9c:49:f5:de:5b:ae:70:cc:2f:8a:95
+ 92:aa:e7:ee:01:84:32:62:b6:81:99:21:21:fa:62:55
+ 18:22:03:9f:9b:d8:db:09:14:28:3f:ec:2e:c7:d1:37
+ 63:8d:dd:bf:2d:7a:9f:50:55:b2:46:a8:fc:f4:57:86
+ c7:f6:06:80:15:a4:13:53:ee:d8:bc:1e:ea:6c:4b:bc
+ 89:24:fb:54:da:9b:c2:35:7f:f7:f1:7b:b3:8b:47:51
+ 81:38:c4:85:90:0c:44:52:f1:67:98:37:13:cb:3f:ad
+ 8f:31:60:16:e5:25:18:fd:11:c5:c8:6c:fd:1c:eb:a1
+
+
+prime1:
+ 00:ca:ea:a1:15:94:16:a5:cd:a2:81:65:af:d5:41:97
+ 15:cb:e9:2f:93:83:7d:7e:58:90:92:de:1a:04:17:94
+ 9b:11:cb:39:6a:55:a0:8d:71:c4:37:eb:70:08:6b:ce
+ 04:a7:e6:e6:85:65:7d:73:d1:72:7d:6d:d5:75:76:4a
+ b0:ef:d7:40:fe:25:4f:50:08:93:b8:f3:65:01:05:5d
+ e5:62:5f:88:d5:2d:7f:1b:d9:3f:24:0d:37:35:02:ba
+ b5:df:0d:8c:ed:66:5d:1a:54:60:04:14:6f:4d:b1:b7
+ 4d:27:c5:d2:a9:85:2b:4e:d0:bf:7d:3e:40:b1:4c:16
+ af:e7:77:af:81:96:fc:28:e8:b4:22:2e:f3:92:18:21
+ ff:0c:38:36:be:26:4c:ac:c3:2a:28:b2:eb:ae:4d:dd
+ cc:84:5e:87:86:d6:7a:c6:a5:38:3a:95:8f:0d:38:75
+ 85:a8:ff:42:98:aa:6b:49:6f:7a:93:60:b6:85:b6:d7
+ d7:
+
+prime2:
+ 00:fb:13:43:33:54:58:5a:6a:3a:ae:da:cb:9b:2a:a0
+ b5:05:29:59:8d:d9:77:d8:fc:40:35:de:53:34:09:a6
+ d7:3a:b8:19:a8:cb:90:13:15:4d:ef:7d:7a:c0:05:3b
+ 53:a7:0f:ef:0e:43:0e:b3:20:2e:24:9d:29:a9:df:ad
+ 0b:91:12:41:5e:c0:3c:ab:3c:cd:5e:af:be:18:65:4b
+ 1d:de:fb:6d:ca:36:d3:95:b6:0e:25:0b:94:e9:86:5f
+ dd:bd:3d:96:e2:c4:6e:a1:87:5c:b7:65:f5:ce:4c:7d
+ fc:03:9e:e6:21:ef:d3:c5:9d:88:b7:4d:67:5d:5c:f5
+ 57:95:37:8f:0d:ad:30:3d:ff:93:55:2b:8b:44:8b:76
+ aa:40:1e:80:86:cc:c4:39:b7:a9:e0:65:77:f6:70:68
+ 42:33:ee:c1:23:b1:a8:84:39:c6:92:a0:2c:74:db:cb
+ e2:7d:b7:d6:12:d7:d0:90:b8:46:88:5f:46:02:e3:55
+ ab:
+
+coefficient:
+ 30:6c:98:d6:5e:3f:9c:83:14:79:60:15:5d:b8:4c:8b
+ 92:f4:c0:62:23:97:be:96:21:26:28:7d:38:08:58:b7
+ 72:04:e4:c3:73:2d:63:23:38:94:89:c6:08:93:44:ad
+ 9f:3d:a4:ad:67:01:89:4d:bf:41:d5:29:72:f7:a3:9b
+ 7d:b0:6b:34:96:27:e9:cf:99:00:b9:ae:80:ed:55:15
+ 32:f4:77:2f:c2:fb:53:4f:9f:ba:08:31:42:12:ee:26
+ aa:b5:87:f1:7a:a7:7e:94:c9:65:ee:8b:7c:bc:73:14
+ 58:4b:d4:fc:82:26:11:75:18:5b:25:0c:4b:c6:80:ff
+ 24:75:d7:f0:c1:4e:00:e6:6d:45:1a:81:7b:0b:1c:77
+ 32:af:8a:8b:d5:b0:31:53:ad:68:35:ac:23:de:f1:f4
+ b1:1c:5e:ff:33:69:9b:65:d9:8e:1f:65:b4:77:ee:3a
+ 80:7f:cd:d3:6e:2e:1d:6c:f7:bb:e7:39:b2:93:3f:33
+
+
+exp1:
+ 04:86:d3:6d:1d:ce:9b:88:48:d5:c6:24:f4:06:f0:8d
+ e5:ec:9f:c9:14:a7:da:07:b3:c1:f2:fe:75:94:e9:15
+ c4:81:da:18:0b:2c:f7:ba:cf:fb:c7:5e:ca:71:4d:39
+ 41:5d:9f:4a:de:86:bb:ec:b2:37:26:1a:1a:f2:b6:9b
+ d7:dd:df:6f:4b:f9:c6:f9:4a:02:58:3b:aa:98:2a:0e
+ 11:f1:bb:a5:b5:cc:1e:1c:ec:91:ab:51:cd:f6:ef:9f
+ 5b:08:7c:5a:57:6c:40:48:1d:94:39:b8:79:ed:3a:ff
+ 97:a1:8c:1f:87:fe:fd:55:1e:d0:76:71:0f:03:79:86
+ 17:0d:ce:76:7f:9d:c4:73:dc:80:de:b7:44:4d:11:85
+ 15:0a:b3:fd:ed:f0:cb:f1:d6:a0:ed:cc:e0:28:90:88
+ 1d:73:d6:66:25:a6:bb:83:b8:0b:66:86:b8:6e:c8:00
+ 61:52:c0:73:93:69:ad:4b:b5:5a:50:50:02:0f:a0:25
+
+
+exp2:
+ 00:cd:04:b6:ac:14:64:ad:37:ef:41:56:e2:49:8b:2e
+ 7d:82:80:78:63:2f:40:01:0c:42:36:7a:9c:00:73:1d
+ 2c:c5:03:0d:d8:da:98:84:2c:b2:5e:2c:5d:6e:ad:16
+ fb:c1:00:6e:d9:7b:82:66:5c:91:b1:4e:30:76:49:72
+ 99:6e:55:b4:d1:75:32:55:35:aa:11:76:7a:48:9b:76
+ 12:27:41:b2:2e:1c:44:fc:0c:14:52:c5:b9:4c:53:70
+ b6:b5:4f:b4:84:e9:97:d9:08:9a:7a:1b:a4:f3:57:5c
+ cc:cb:fc:15:b9:82:87:af:e7:6a:7b:1b:96:9b:13:4c
+ 37:bf:5e:05:cf:4a:2b:89:84:c7:bf:15:76:7c:7b:51
+ 63:c6:45:e1:f7:b0:ff:4e:8e:1e:06:61:74:ea:e4:71
+ 0e:16:30:10:c0:5f:d2:d6:5e:03:3b:39:d5:f3:7a:83
+ 6b:27:f3:54:b8:40:48:4b:d4:5d:ab:ff:f8:40:65:78
+ 4f:
+
+
+Public Key ID: 0C:11:36:9D:B0:9C:05:44:64:AC:97:26:40:C0:28:53:23:9D:8E:9A
+Public key's random art:
++--[ RSA 3072]----+
+|==+. =%=.. |
+|+o+. +.*o |
+|.+ . .=. |
+|. . o +o |
+|.. + S |
+|E |
+| |
+| |
+| |
++-----------------+
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4wIBAAKCAYEAxwNQnjSN9Hp+zihif6VsjUh/a58PM+noA8XU47TiInIQNvy1
+T2hmWHnCNBh/1LZEYDOvZBbqOnUWlr69Mqflz3xpQHBXD4OnGChKGMm9fB7E0Xsr
+gHHQXGEGINmXZgKranhwKnG+8EhAfF7ly3Q9hZbHKNxmk98xTb+7e0BQ1tW9rU//
+dsPkBrSNU6+SwjFWyEkRkkM4Qr9vZd1LVreEigPVvMoYOczCZDBMWlCVbVYkRZQB
+cyq1FShamfLLM8tslyHEy7JCSXOYn/KOXKVgq23F0m+U7BwPuBRzgeqLtM+/7Ny8
+GI6H9OemcosY9CzOLE2CBLbQ7ixEUb2EyIbS4ZQNgVnwH7lvWxrqINAvcRqbffb5
+4hyZSpjJrKs+YRAy2M4lBH4+as0sSjHANlQnjtQ4Go0nnYdd1Tf7FlMpOWigO9Yu
+NAp6eKCv7s3mFu71pf7bQhBXOsfKc3jHaAY79SXfYQtGdlILbQvypzEyl98ujUdT
+1RYw0NzCAOwYcY+dAgMBAAECggGAJTFhZ6+6t+4MtMqnXeO0ndLmvV5EoRcd3Vaj
+qsqrWHSowx4HZIfGWNKokMPjYAWQUcpXBQWjULmBNzr+cPEf6d7+bKSSILwiBknB
+T1CksQWvEtdKEf8zSZB4bLs9qDrnfkZz7/rCDHX0V0oE+DkJJmY/YkuOgCQ+OqGS
+kD483WmkwTcqLy/89aPYpcMyUkiWR2ggeI1HfnH4h7kL03EIvCJrV5UNYf/6dG7y
+Vg6pXn2y2a4Hd1aL8SBRjmPpxgxGMj/aPZcqfY1EQmOtVah5E0E14IVVwDCUHZXw
+6VVOwM/OOfMYOOK71bMIwuvLIDcIWA1SvO5FvFYhMTzT7gLLcepZ19XCnEn13luu
+cMwvipWSqufuAYQyYraBmSEh+mJVGCIDn5vY2wkUKD/sLsfRN2ON3b8tep9QVbJG
+qPz0V4bH9gaAFaQTU+7YvB7qbEu8iST7VNqbwjV/9/F7s4tHUYE4xIWQDERS8WeY
+NxPLP62PMWAW5SUY/RHFyGz9HOuhAoHBAMrqoRWUFqXNooFlr9VBlxXL6S+Tg31+
+WJCS3hoEF5SbEcs5alWgjXHEN+twCGvOBKfm5oVlfXPRcn1t1XV2SrDv10D+JU9Q
+CJO482UBBV3lYl+I1S1/G9k/JA03NQK6td8NjO1mXRpUYAQUb02xt00nxdKphStO
+0L99PkCxTBav53evgZb8KOi0Ii7zkhgh/ww4Nr4mTKzDKiiy665N3cyEXoeG1nrG
+pTg6lY8NOHWFqP9CmKprSW96k2C2hbbX1wKBwQD7E0MzVFhaajqu2subKqC1BSlZ
+jdl32PxANd5TNAmm1zq4GajLkBMVTe99esAFO1OnD+8OQw6zIC4knSmp360LkRJB
+XsA8qzzNXq++GGVLHd77bco205W2DiULlOmGX929PZbixG6hh1y3ZfXOTH38A57m
+Ie/TxZ2It01nXVz1V5U3jw2tMD3/k1Uri0SLdqpAHoCGzMQ5t6ngZXf2cGhCM+7B
+I7GohDnGkqAsdNvL4n231hLX0JC4RohfRgLjVasCgcAEhtNtHc6biEjVxiT0BvCN
+5eyfyRSn2gezwfL+dZTpFcSB2hgLLPe6z/vHXspxTTlBXZ9K3oa77LI3Jhoa8rab
+193fb0v5xvlKAlg7qpgqDhHxu6W1zB4c7JGrUc32759bCHxaV2xASB2UObh57Tr/
+l6GMH4f+/VUe0HZxDwN5hhcNznZ/ncRz3IDet0RNEYUVCrP97fDL8dag7czgKJCI
+HXPWZiWmu4O4C2aGuG7IAGFSwHOTaa1LtVpQUAIPoCUCgcEAzQS2rBRkrTfvQVbi
+SYsufYKAeGMvQAEMQjZ6nABzHSzFAw3Y2piELLJeLF1urRb7wQBu2XuCZlyRsU4w
+dklymW5VtNF1MlU1qhF2ekibdhInQbIuHET8DBRSxblMU3C2tU+0hOmX2Qiaehuk
+81dczMv8FbmCh6/nansblpsTTDe/XgXPSiuJhMe/FXZ8e1FjxkXh97D/To4eBmF0
+6uRxDhYwEMBf0tZeAzs51fN6g2sn81S4QEhL1F2r//hAZXhPAoHAMGyY1l4/nIMU
+eWAVXbhMi5L0wGIjl76WISYofTgIWLdyBOTDcy1jIziUicYIk0Stnz2krWcBiU2/
+QdUpcvejm32wazSWJ+nPmQC5roDtVRUy9HcvwvtTT5+6CDFCEu4mqrWH8XqnfpTJ
+Ze6LfLxzFFhL1PyCJhF1GFslDEvGgP8kddfwwU4A5m1FGoF7Cxx3Mq+Ki9WwMVOt
+aDWsI97x9LEcXv8zaZtl2Y4fZbR37jqAf83Tbi4dbPe75zmykz8z
+-----END RSA PRIVATE KEY-----
diff --git a/tests/tls-certs/ca.pem b/tests/tls-certs/ca.pem
new file mode 100644
index 0000000..99925c4
--- /dev/null
+++ b/tests/tls-certs/ca.pem
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE9jCCA16gAwIBAgIIWxfM+RyuD1EwDQYJKoZIhvcNAQELBQAwgYsxEzARBgNV
+BAMTCnJzeXNsb2cgY2ExEDAOBgNVBAsTB0FkaXNjb24xFTATBgNVBAoTDEFkaXNj
+b24gR21iSDEYMBYGA1UEBxMPR3Jvc3NyaW5kZXJmZWxkMQswCQYDVQQIEwJCVzEL
+MAkGA1UEBhMCREUxFzAVBgoJkiaJk/IsZAEZFgdyc3lzbG9nMCAXDTE4MDYwNjEy
+MDA1OFoYDzIxMTgwNTEzMTIwMTA1WjCBizETMBEGA1UEAxMKcnN5c2xvZyBjYTEQ
+MA4GA1UECxMHQWRpc2NvbjEVMBMGA1UEChMMQWRpc2NvbiBHbWJIMRgwFgYDVQQH
+Ew9Hcm9zc3JpbmRlcmZlbGQxCzAJBgNVBAgTAkJXMQswCQYDVQQGEwJERTEXMBUG
+CgmSJomT8ixkARkWB3JzeXNsb2cwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGK
+AoIBgQDHA1CeNI30en7OKGJ/pWyNSH9rnw8z6egDxdTjtOIichA2/LVPaGZYecI0
+GH/UtkRgM69kFuo6dRaWvr0yp+XPfGlAcFcPg6cYKEoYyb18HsTReyuAcdBcYQYg
+2ZdmAqtqeHAqcb7wSEB8XuXLdD2Flsco3GaT3zFNv7t7QFDW1b2tT/92w+QGtI1T
+r5LCMVbISRGSQzhCv29l3UtWt4SKA9W8yhg5zMJkMExaUJVtViRFlAFzKrUVKFqZ
+8sszy2yXIcTLskJJc5if8o5cpWCrbcXSb5TsHA+4FHOB6ou0z7/s3LwYjof056Zy
+ixj0LM4sTYIEttDuLERRvYTIhtLhlA2BWfAfuW9bGuog0C9xGpt99vniHJlKmMms
+qz5hEDLYziUEfj5qzSxKMcA2VCeO1DgajSedh13VN/sWUyk5aKA71i40Cnp4oK/u
+zeYW7vWl/ttCEFc6x8pzeMdoBjv1Jd9hC0Z2UgttC/KnMTKX3y6NR1PVFjDQ3MIA
+7Bhxj50CAwEAAaNaMFgwDwYDVR0TAQH/BAUwAwEB/zAVBgNVHREEDjAMggpyc3lz
+bG9nIGNhMA8GA1UdDwEB/wQFAwMHBAAwHQYDVR0OBBYEFAwRNp2wnAVEZKyXJkDA
+KFMjnY6aMA0GCSqGSIb3DQEBCwUAA4IBgQCOv2kyg8vZ3jncZuZ4i2k0QbXztZoO
+jMDNqFX2935lK6WrVZ6u1InZzsaqrXXOJions3EvmmAqrdTBW6dyw6V2/lic1gGz
+MhlafAPe0DyQCaXp9iFCH91Hzo94YhuPbne1qdga9jrVTiQIHdIKqVtbiUv7i7mN
+43GssOm4a1guf+Qs5rkuHG4YwiJZhjzhmixfXCerHXykJkpSvBUb6EeKA+p5/w+I
+Wjm9sAkJgqcvrNvOwwBZInU1I56zmM0ZwWucSydf0hgOImpgO5F6KGVQRoZsO9IA
+Iju2RQ1y9qVTNp8evVjIMuqXh5ZtU9ti/buZrjr5Zb601jFLZCMrpDVUcVyHUfOB
+rb3nkUFDcFcrKlfovwp/fvlISKM0bp6pFas5X0FXg3sVVI+iIokmHsmqRUHhjdLX
+t27+/TYpyEkjF1cH3acd7MOcw33KxE/4+qUHT2QU9COPkGu7oPS24qDYnmGPLkev
+ZSmpz4jLTmbCBSRcoOB0Q4K36WnegzVtvd8=
+-----END CERTIFICATE-----
diff --git a/tests/tls-certs/cert-fail.pem b/tests/tls-certs/cert-fail.pem
new file mode 100644
index 0000000..7318f36
--- /dev/null
+++ b/tests/tls-certs/cert-fail.pem
@@ -0,0 +1,3 @@
+-----BEGIN CERTIFICATE-----
+this is an invalid cert
+-----END CERTIFICATE-----
diff --git a/tests/tls-certs/cert.pem b/tests/tls-certs/cert.pem
new file mode 100644
index 0000000..58cdec3
--- /dev/null
+++ b/tests/tls-certs/cert.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFVzCCA7+gAwIBAgIIWxfNMhQmuncwDQYJKoZIhvcNAQELBQAwgYsxEzARBgNV
+BAMTCnJzeXNsb2cgY2ExEDAOBgNVBAsTB0FkaXNjb24xFTATBgNVBAoTDEFkaXNj
+b24gR21iSDEYMBYGA1UEBxMPR3Jvc3NyaW5kZXJmZWxkMQswCQYDVQQIEwJCVzEL
+MAkGA1UEBhMCREUxFzAVBgoJkiaJk/IsZAEZFgdyc3lzbG9nMCAXDTE4MDYwNjEy
+MDE1NVoYDzIxMTgwNTEzMTIwMjAxWjCBmDEXMBUGA1UEAxMOcnN5c2xvZy1jbGll
+bnQxFTATBgNVBAsTDEFkaXNjb24gR21iSDEVMBMGA1UEChMMQWRpc2NvbiBHbWJI
+MRgwFgYDVQQHEw9Hcm9zc3JpbmRlcmZlbGQxCzAJBgNVBAgTAkJXMQswCQYDVQQG
+EwJERTEbMBkGCgmSJomT8ixkARkWC3JzeXNsb2cuY29tMIIBojANBgkqhkiG9w0B
+AQEFAAOCAY8AMIIBigKCAYEA8nNWVoZwi7fYKSYxm+lidTbMQEHh9pLXV8P1N2FD
+wqhNc6Z71VqQw6gIDyzxBjZf3ldyPb6xAcxikvk2XCxVGqDaP7E1rfnCDSqxcgLG
+r1/TlRH3fFMFPqzMgs0GbDoKi7WuhcNMH1yIRk4uPVSUY3IclcE9sNvMpNVY77c9
+tYeLyoLgG8A2ljlSjbHXDmR8E1C+WcOvjFKQunpv29zIOvfp3Wuw0g3C6E26RyvY
+OnNNq6bmDHXdyIkxYNPwxyfBDGq/WhnrFqQTyEqulVLVVIpK+3fIdtmH/4OpOwxz
+KM0q2k9CzL+AI1JqlFoePeIKYQYAOssUBwB0VBDbhyo8f7txBs6OB1phPcmbkAo2
+bJfL01UT315omqlGWjvvDRjDEeRAfXnWu/UVLIs1MNn09l2+fKwgZyOZIQEk5gGg
+b+xO7pZp5W1IuLxB1DMatQjYK1L1MG8KUebovTyumAj8kOaCJaqa+EWcPvsH2wJb
+zp7JZV7xAMnNQGLHHccY9Iv9AgMBAAGjga0wgaowDAYDVR0TAQH/BAIwADAnBgNV
+HSUEIDAeBggrBgEFBQcDAgYIKwYBBQUHAwEGCCsGAQUFBwMRMCAGA1UdEQQZMBeC
+FXRlc3RiZW5jaC5yc3lzbG9nLmNvbTAPBgNVHQ8BAf8EBQMDB6AAMB0GA1UdDgQW
+BBTFQ9rF9eWMeqNtrDMOGb1fZ54EYTAfBgNVHSMEGDAWgBQMETadsJwFRGSslyZA
+wChTI52OmjANBgkqhkiG9w0BAQsFAAOCAYEAG9hahjpm74U85pP7/zngEJ5P5nnM
+3aC8u4lDM7kodtnxJWoisbv/EBr6SihpDtfWA6+bAJGGu+4UBUaMyUg8w/FjylHc
+INtljbalRuu7YguL2uLdlDNCxQa1XkWugYMObR6r6OvTPUwK0QakTsZuibRbWBDz
+lWKOoM7ZSxZi9DaeChe3yNSGxJSC9xHZbYYBOP5RjChXTZTKtYZemF2wx6EtWRtc
+vXK3TbnJtDy7SPm60EoFnLXUyywmo5mCUSlx85HinS1DzYo7I1yksWQgdW4XgWId
+9RgwPtP0iZSjrZ1TwKqcvo5jvn96LNCoob+JyhpL+9mFvPc6C3vLOxyG7JZOb7Dn
+IpJf52KeBnLRUoIpp+x1XYptoy1ti7r8YqPYn5EHmPxCDVoujskRSX7ncP3SV1qY
+eEgr94Tw/l8GyiaGyixVl2pAMbzYJtgrzQ9UvZurhSPjApGlm87X5KHHXN/CJTY5
+8t59+qvjESRJk74JNpm1L6X/N7HpAsqcsYjP
+-----END CERTIFICATE-----
diff --git a/tests/tls-certs/certchained.pem b/tests/tls-certs/certchained.pem
new file mode 100644
index 0000000..e35b220
--- /dev/null
+++ b/tests/tls-certs/certchained.pem
@@ -0,0 +1,60 @@
+-----BEGIN CERTIFICATE-----
+MIIFVzCCA7+gAwIBAgIIWxfNMhQmuncwDQYJKoZIhvcNAQELBQAwgYsxEzARBgNV
+BAMTCnJzeXNsb2cgY2ExEDAOBgNVBAsTB0FkaXNjb24xFTATBgNVBAoTDEFkaXNj
+b24gR21iSDEYMBYGA1UEBxMPR3Jvc3NyaW5kZXJmZWxkMQswCQYDVQQIEwJCVzEL
+MAkGA1UEBhMCREUxFzAVBgoJkiaJk/IsZAEZFgdyc3lzbG9nMCAXDTE4MDYwNjEy
+MDE1NVoYDzIxMTgwNTEzMTIwMjAxWjCBmDEXMBUGA1UEAxMOcnN5c2xvZy1jbGll
+bnQxFTATBgNVBAsTDEFkaXNjb24gR21iSDEVMBMGA1UEChMMQWRpc2NvbiBHbWJI
+MRgwFgYDVQQHEw9Hcm9zc3JpbmRlcmZlbGQxCzAJBgNVBAgTAkJXMQswCQYDVQQG
+EwJERTEbMBkGCgmSJomT8ixkARkWC3JzeXNsb2cuY29tMIIBojANBgkqhkiG9w0B
+AQEFAAOCAY8AMIIBigKCAYEA8nNWVoZwi7fYKSYxm+lidTbMQEHh9pLXV8P1N2FD
+wqhNc6Z71VqQw6gIDyzxBjZf3ldyPb6xAcxikvk2XCxVGqDaP7E1rfnCDSqxcgLG
+r1/TlRH3fFMFPqzMgs0GbDoKi7WuhcNMH1yIRk4uPVSUY3IclcE9sNvMpNVY77c9
+tYeLyoLgG8A2ljlSjbHXDmR8E1C+WcOvjFKQunpv29zIOvfp3Wuw0g3C6E26RyvY
+OnNNq6bmDHXdyIkxYNPwxyfBDGq/WhnrFqQTyEqulVLVVIpK+3fIdtmH/4OpOwxz
+KM0q2k9CzL+AI1JqlFoePeIKYQYAOssUBwB0VBDbhyo8f7txBs6OB1phPcmbkAo2
+bJfL01UT315omqlGWjvvDRjDEeRAfXnWu/UVLIs1MNn09l2+fKwgZyOZIQEk5gGg
+b+xO7pZp5W1IuLxB1DMatQjYK1L1MG8KUebovTyumAj8kOaCJaqa+EWcPvsH2wJb
+zp7JZV7xAMnNQGLHHccY9Iv9AgMBAAGjga0wgaowDAYDVR0TAQH/BAIwADAnBgNV
+HSUEIDAeBggrBgEFBQcDAgYIKwYBBQUHAwEGCCsGAQUFBwMRMCAGA1UdEQQZMBeC
+FXRlc3RiZW5jaC5yc3lzbG9nLmNvbTAPBgNVHQ8BAf8EBQMDB6AAMB0GA1UdDgQW
+BBTFQ9rF9eWMeqNtrDMOGb1fZ54EYTAfBgNVHSMEGDAWgBQMETadsJwFRGSslyZA
+wChTI52OmjANBgkqhkiG9w0BAQsFAAOCAYEAG9hahjpm74U85pP7/zngEJ5P5nnM
+3aC8u4lDM7kodtnxJWoisbv/EBr6SihpDtfWA6+bAJGGu+4UBUaMyUg8w/FjylHc
+INtljbalRuu7YguL2uLdlDNCxQa1XkWugYMObR6r6OvTPUwK0QakTsZuibRbWBDz
+lWKOoM7ZSxZi9DaeChe3yNSGxJSC9xHZbYYBOP5RjChXTZTKtYZemF2wx6EtWRtc
+vXK3TbnJtDy7SPm60EoFnLXUyywmo5mCUSlx85HinS1DzYo7I1yksWQgdW4XgWId
+9RgwPtP0iZSjrZ1TwKqcvo5jvn96LNCoob+JyhpL+9mFvPc6C3vLOxyG7JZOb7Dn
+IpJf52KeBnLRUoIpp+x1XYptoy1ti7r8YqPYn5EHmPxCDVoujskRSX7ncP3SV1qY
+eEgr94Tw/l8GyiaGyixVl2pAMbzYJtgrzQ9UvZurhSPjApGlm87X5KHHXN/CJTY5
+8t59+qvjESRJk74JNpm1L6X/N7HpAsqcsYjP
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIE9jCCA16gAwIBAgIIWxfM+RyuD1EwDQYJKoZIhvcNAQELBQAwgYsxEzARBgNV
+BAMTCnJzeXNsb2cgY2ExEDAOBgNVBAsTB0FkaXNjb24xFTATBgNVBAoTDEFkaXNj
+b24gR21iSDEYMBYGA1UEBxMPR3Jvc3NyaW5kZXJmZWxkMQswCQYDVQQIEwJCVzEL
+MAkGA1UEBhMCREUxFzAVBgoJkiaJk/IsZAEZFgdyc3lzbG9nMCAXDTE4MDYwNjEy
+MDA1OFoYDzIxMTgwNTEzMTIwMTA1WjCBizETMBEGA1UEAxMKcnN5c2xvZyBjYTEQ
+MA4GA1UECxMHQWRpc2NvbjEVMBMGA1UEChMMQWRpc2NvbiBHbWJIMRgwFgYDVQQH
+Ew9Hcm9zc3JpbmRlcmZlbGQxCzAJBgNVBAgTAkJXMQswCQYDVQQGEwJERTEXMBUG
+CgmSJomT8ixkARkWB3JzeXNsb2cwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGK
+AoIBgQDHA1CeNI30en7OKGJ/pWyNSH9rnw8z6egDxdTjtOIichA2/LVPaGZYecI0
+GH/UtkRgM69kFuo6dRaWvr0yp+XPfGlAcFcPg6cYKEoYyb18HsTReyuAcdBcYQYg
+2ZdmAqtqeHAqcb7wSEB8XuXLdD2Flsco3GaT3zFNv7t7QFDW1b2tT/92w+QGtI1T
+r5LCMVbISRGSQzhCv29l3UtWt4SKA9W8yhg5zMJkMExaUJVtViRFlAFzKrUVKFqZ
+8sszy2yXIcTLskJJc5if8o5cpWCrbcXSb5TsHA+4FHOB6ou0z7/s3LwYjof056Zy
+ixj0LM4sTYIEttDuLERRvYTIhtLhlA2BWfAfuW9bGuog0C9xGpt99vniHJlKmMms
+qz5hEDLYziUEfj5qzSxKMcA2VCeO1DgajSedh13VN/sWUyk5aKA71i40Cnp4oK/u
+zeYW7vWl/ttCEFc6x8pzeMdoBjv1Jd9hC0Z2UgttC/KnMTKX3y6NR1PVFjDQ3MIA
+7Bhxj50CAwEAAaNaMFgwDwYDVR0TAQH/BAUwAwEB/zAVBgNVHREEDjAMggpyc3lz
+bG9nIGNhMA8GA1UdDwEB/wQFAwMHBAAwHQYDVR0OBBYEFAwRNp2wnAVEZKyXJkDA
+KFMjnY6aMA0GCSqGSIb3DQEBCwUAA4IBgQCOv2kyg8vZ3jncZuZ4i2k0QbXztZoO
+jMDNqFX2935lK6WrVZ6u1InZzsaqrXXOJions3EvmmAqrdTBW6dyw6V2/lic1gGz
+MhlafAPe0DyQCaXp9iFCH91Hzo94YhuPbne1qdga9jrVTiQIHdIKqVtbiUv7i7mN
+43GssOm4a1guf+Qs5rkuHG4YwiJZhjzhmixfXCerHXykJkpSvBUb6EeKA+p5/w+I
+Wjm9sAkJgqcvrNvOwwBZInU1I56zmM0ZwWucSydf0hgOImpgO5F6KGVQRoZsO9IA
+Iju2RQ1y9qVTNp8evVjIMuqXh5ZtU9ti/buZrjr5Zb601jFLZCMrpDVUcVyHUfOB
+rb3nkUFDcFcrKlfovwp/fvlISKM0bp6pFas5X0FXg3sVVI+iIokmHsmqRUHhjdLX
+t27+/TYpyEkjF1cH3acd7MOcw33KxE/4+qUHT2QU9COPkGu7oPS24qDYnmGPLkev
+ZSmpz4jLTmbCBSRcoOB0Q4K36WnegzVtvd8=
+-----END CERTIFICATE-----
diff --git a/tests/tls-certs/key-fail.pem b/tests/tls-certs/key-fail.pem
new file mode 100644
index 0000000..2335af1
--- /dev/null
+++ b/tests/tls-certs/key-fail.pem
@@ -0,0 +1,40 @@
+# first line of Key is invalidated
+-----BEGIN RSA PRIVATE KEY-----
+0000000000000000000000000000000000000000000000000000000000000000
+1VqQw6gIDyzxBjZf3ldyPb6xAcxikvk2XCxVGqDaP7E1rfnCDSqxcgLGr1/TlRH3
+fFMFPqzMgs0GbDoKi7WuhcNMH1yIRk4uPVSUY3IclcE9sNvMpNVY77c9tYeLyoLg
+G8A2ljlSjbHXDmR8E1C+WcOvjFKQunpv29zIOvfp3Wuw0g3C6E26RyvYOnNNq6bm
+DHXdyIkxYNPwxyfBDGq/WhnrFqQTyEqulVLVVIpK+3fIdtmH/4OpOwxzKM0q2k9C
+zL+AI1JqlFoePeIKYQYAOssUBwB0VBDbhyo8f7txBs6OB1phPcmbkAo2bJfL01UT
+315omqlGWjvvDRjDEeRAfXnWu/UVLIs1MNn09l2+fKwgZyOZIQEk5gGgb+xO7pZp
+5W1IuLxB1DMatQjYK1L1MG8KUebovTyumAj8kOaCJaqa+EWcPvsH2wJbzp7JZV7x
+AMnNQGLHHccY9Iv9AgMBAAECggGAY6qwOl+H0pff34KY8Cvv0pmVO3EZ7+ALcEPZ
+AUwVq+a9+CXfUCSr0BK6RWrHJjOiE2fFScajQ0b+2sZh52A+F/U54ub5VyyN7hW3
+3lNv09ZDx0scftouFMa6R6b61fDCNw6X0Nso5teGGci3z3R+j6bwQ0uuDY89wCEI
+L3sXfhFbkQNeF2pbxkOIQUFzU7JRIyuVJJeCCeBDKLV+WFaZZUxWsjQ7+w23KwIQ
+6oMGn3iY3FB+z26AnphvWQunNmeLcq11lpwTpI4XB21FMLFVA4FlawLhMP6ca2OA
+rp1HsTPqthxtFC//KXHinN1AYjQERD2NcWvR6o1GYzcSJo+UHPVq0WZ/qdbdWSd5
+zuqts0diufYcNgrA/vP24cKGEpf58n5itDM+rUMFlR0U/r52xkQ4gKQlCFtcdk6p
+vap/8QWLSYGgQEsamNHJz5jhunES/B9TqldcZTrgciTVjychnPy21vfIB1zCQl3L
+ur8N8hObB2tzrhvwtxpq/SDPsnIBAoHBAP4UzzGg2OD1STUiLBQTqlXWJpLC+mMC
+ct3RBdEPsKSu5A6ZoDXjhCQGqidNzm8zbYqWPlS9UZLpP5vybp19Hi/hEbzbNMgv
+qwfuSl2WBVQcSPA8g5k6n13+MUgMswyr41wt5wZDkVxiIXYKTwDso5WFsP47YYsH
+xyG7tO8N0WcB3b2b6FbryiKDweiJO/oXI+ne/WIEcx8qiWbX0RaZf5ig4MKbESIj
+uVXLoEvrgaSogl3gCssZ/Rhd4hfMEysZgQKBwQD0SAsWOOjZlH44KXHUKvp8zdi1
+0tvRpj8fPzkv8q89rozJ/QEyg89I9PUllT8Kg5AhdWBSAZpeldLtTG6M+ZOaQCS1
+kevmtJZqalEbmxj9JMjDaFLjVfUj4JdNS0vNgwS54XC2TEKmoAwuDfChwAQIVw/a
+Dg7uMnwg5gPuNUEiAbDzbu4N15Ed7ZjU7+YD8TmW3aAfbDo92dKs8BNzMc+x+xPT
+VVUbbL05SeB6t+/sPVzdfb+gEWmPZvxFKbMFGH0CgcEA25yU8ep7SwX4PurIepn8
+0rCFKrlIvqdxLXTruCX9onpgOJZkue9rWdBA5jQESG2FMxJl0czJY1gkWOCU558r
+pmq9cCVwW8+H3xUCRh3TgT3pdWx4usrG0PFTG1mOsVco75XlZ66jR9yx21tRqhTf
+1+90ampdB1Szs96Qp0ekRYqBZNALZIXtcyO7SQjFRIcXzZ+mF0CNWNTlanUEDqqi
+dQQpAUwS5RVHrnaQmM54gh/8frOV4LMX5iXPtI35y3kBAoHBAK3RqZnpar6Pq/R4
+gReQcWZm7qIKZQHbwqSQTzfv/oPsdR+xGK4CHnfyXZGdjhsEHIXCSIRxwY82Gr1h
+mnRTjpS+uaA9MdeafkFAX3A+P1y5VOW+kORUoLcjs2V7g3e7l5xQbuw4fWClF6WZ
+o7TktbndgVkOkc8qOysJoJhaansxKuE8+MT+s7LRAuPZxBjgB7NzBeH2F8c0/HSz
+65MXSYuCdcv1tzZpfIeMKuAHi//UdgTg2n6ihTNV+4GXN1wT3QKBwQCbC2bX/t1p
+0ppb1U428MhnTmj/1SGhklAnl0dugj2zxYfSwBUJwZ7cLXRazCvKggpdO4KTMc4S
+vVt9VIfAig7fhtZvYspKQV9sjsusbjfAuCYgw1k3zh/n66UIirCW8+A9/GbEa2YU
+kXYsIuRqViBBUWp38b9MW+j6r0EJqHdaamZtEoNUwej/tzrbn0bizthgqAMjeEFf
+++oWYiAkjYtJZOTLyoPoxGCX+7/n3CwQugNndupNAGwG+NKD+yb+3OE=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/tls-certs/key.pem b/tests/tls-certs/key.pem
new file mode 100644
index 0000000..4d63250
--- /dev/null
+++ b/tests/tls-certs/key.pem
@@ -0,0 +1,190 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:f2:73:56:56:86:70:8b:b7:d8:29:26:31:9b:e9:62
+ 75:36:cc:40:41:e1:f6:92:d7:57:c3:f5:37:61:43:c2
+ a8:4d:73:a6:7b:d5:5a:90:c3:a8:08:0f:2c:f1:06:36
+ 5f:de:57:72:3d:be:b1:01:cc:62:92:f9:36:5c:2c:55
+ 1a:a0:da:3f:b1:35:ad:f9:c2:0d:2a:b1:72:02:c6:af
+ 5f:d3:95:11:f7:7c:53:05:3e:ac:cc:82:cd:06:6c:3a
+ 0a:8b:b5:ae:85:c3:4c:1f:5c:88:46:4e:2e:3d:54:94
+ 63:72:1c:95:c1:3d:b0:db:cc:a4:d5:58:ef:b7:3d:b5
+ 87:8b:ca:82:e0:1b:c0:36:96:39:52:8d:b1:d7:0e:64
+ 7c:13:50:be:59:c3:af:8c:52:90:ba:7a:6f:db:dc:c8
+ 3a:f7:e9:dd:6b:b0:d2:0d:c2:e8:4d:ba:47:2b:d8:3a
+ 73:4d:ab:a6:e6:0c:75:dd:c8:89:31:60:d3:f0:c7:27
+ c1:0c:6a:bf:5a:19:eb:16:a4:13:c8:4a:ae:95:52:d5
+ 54:8a:4a:fb:77:c8:76:d9:87:ff:83:a9:3b:0c:73:28
+ cd:2a:da:4f:42:cc:bf:80:23:52:6a:94:5a:1e:3d:e2
+ 0a:61:06:00:3a:cb:14:07:00:74:54:10:db:87:2a:3c
+ 7f:bb:71:06:ce:8e:07:5a:61:3d:c9:9b:90:0a:36:6c
+ 97:cb:d3:55:13:df:5e:68:9a:a9:46:5a:3b:ef:0d:18
+ c3:11:e4:40:7d:79:d6:bb:f5:15:2c:8b:35:30:d9:f4
+ f6:5d:be:7c:ac:20:67:23:99:21:01:24:e6:01:a0:6f
+ ec:4e:ee:96:69:e5:6d:48:b8:bc:41:d4:33:1a:b5:08
+ d8:2b:52:f5:30:6f:0a:51:e6:e8:bd:3c:ae:98:08:fc
+ 90:e6:82:25:aa:9a:f8:45:9c:3e:fb:07:db:02:5b:ce
+ 9e:c9:65:5e:f1:00:c9:cd:40:62:c7:1d:c7:18:f4:8b
+ fd:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 63:aa:b0:3a:5f:87:d2:97:df:df:82:98:f0:2b:ef:d2
+ 99:95:3b:71:19:ef:e0:0b:70:43:d9:01:4c:15:ab:e6
+ bd:f8:25:df:50:24:ab:d0:12:ba:45:6a:c7:26:33:a2
+ 13:67:c5:49:c6:a3:43:46:fe:da:c6:61:e7:60:3e:17
+ f5:39:e2:e6:f9:57:2c:8d:ee:15:b7:de:53:6f:d3:d6
+ 43:c7:4b:1c:7e:da:2e:14:c6:ba:47:a6:fa:d5:f0:c2
+ 37:0e:97:d0:db:28:e6:d7:86:19:c8:b7:cf:74:7e:8f
+ a6:f0:43:4b:ae:0d:8f:3d:c0:21:08:2f:7b:17:7e:11
+ 5b:91:03:5e:17:6a:5b:c6:43:88:41:41:73:53:b2:51
+ 23:2b:95:24:97:82:09:e0:43:28:b5:7e:58:56:99:65
+ 4c:56:b2:34:3b:fb:0d:b7:2b:02:10:ea:83:06:9f:78
+ 98:dc:50:7e:cf:6e:80:9e:98:6f:59:0b:a7:36:67:8b
+ 72:ad:75:96:9c:13:a4:8e:17:07:6d:45:30:b1:55:03
+ 81:65:6b:02:e1:30:fe:9c:6b:63:80:ae:9d:47:b1:33
+ ea:b6:1c:6d:14:2f:ff:29:71:e2:9c:dd:40:62:34:04
+ 44:3d:8d:71:6b:d1:ea:8d:46:63:37:12:26:8f:94:1c
+ f5:6a:d1:66:7f:a9:d6:dd:59:27:79:ce:ea:ad:b3:47
+ 62:b9:f6:1c:36:0a:c0:fe:f3:f6:e1:c2:86:12:97:f9
+ f2:7e:62:b4:33:3e:ad:43:05:95:1d:14:fe:be:76:c6
+ 44:38:80:a4:25:08:5b:5c:76:4e:a9:bd:aa:7f:f1:05
+ 8b:49:81:a0:40:4b:1a:98:d1:c9:cf:98:e1:ba:71:12
+ fc:1f:53:aa:57:5c:65:3a:e0:72:24:d5:8f:27:21:9c
+ fc:b6:d6:f7:c8:07:5c:c2:42:5d:cb:ba:bf:0d:f2:13
+ 9b:07:6b:73:ae:1b:f0:b7:1a:6a:fd:20:cf:b2:72:01
+
+
+prime1:
+ 00:fe:14:cf:31:a0:d8:e0:f5:49:35:22:2c:14:13:aa
+ 55:d6:26:92:c2:fa:63:02:72:dd:d1:05:d1:0f:b0:a4
+ ae:e4:0e:99:a0:35:e3:84:24:06:aa:27:4d:ce:6f:33
+ 6d:8a:96:3e:54:bd:51:92:e9:3f:9b:f2:6e:9d:7d:1e
+ 2f:e1:11:bc:db:34:c8:2f:ab:07:ee:4a:5d:96:05:54
+ 1c:48:f0:3c:83:99:3a:9f:5d:fe:31:48:0c:b3:0c:ab
+ e3:5c:2d:e7:06:43:91:5c:62:21:76:0a:4f:00:ec:a3
+ 95:85:b0:fe:3b:61:8b:07:c7:21:bb:b4:ef:0d:d1:67
+ 01:dd:bd:9b:e8:56:eb:ca:22:83:c1:e8:89:3b:fa:17
+ 23:e9:de:fd:62:04:73:1f:2a:89:66:d7:d1:16:99:7f
+ 98:a0:e0:c2:9b:11:22:23:b9:55:cb:a0:4b:eb:81:a4
+ a8:82:5d:e0:0a:cb:19:fd:18:5d:e2:17:cc:13:2b:19
+ 81:
+
+prime2:
+ 00:f4:48:0b:16:38:e8:d9:94:7e:38:29:71:d4:2a:fa
+ 7c:cd:d8:b5:d2:db:d1:a6:3f:1f:3f:39:2f:f2:af:3d
+ ae:8c:c9:fd:01:32:83:cf:48:f4:f5:25:95:3f:0a:83
+ 90:21:75:60:52:01:9a:5e:95:d2:ed:4c:6e:8c:f9:93
+ 9a:40:24:b5:91:eb:e6:b4:96:6a:6a:51:1b:9b:18:fd
+ 24:c8:c3:68:52:e3:55:f5:23:e0:97:4d:4b:4b:cd:83
+ 04:b9:e1:70:b6:4c:42:a6:a0:0c:2e:0d:f0:a1:c0:04
+ 08:57:0f:da:0e:0e:ee:32:7c:20:e6:03:ee:35:41:22
+ 01:b0:f3:6e:ee:0d:d7:91:1d:ed:98:d4:ef:e6:03:f1
+ 39:96:dd:a0:1f:6c:3a:3d:d9:d2:ac:f0:13:73:31:cf
+ b1:fb:13:d3:55:55:1b:6c:bd:39:49:e0:7a:b7:ef:ec
+ 3d:5c:dd:7d:bf:a0:11:69:8f:66:fc:45:29:b3:05:18
+ 7d:
+
+coefficient:
+ 00:9b:0b:66:d7:fe:dd:69:d2:9a:5b:d5:4e:36:f0:c8
+ 67:4e:68:ff:d5:21:a1:92:50:27:97:47:6e:82:3d:b3
+ c5:87:d2:c0:15:09:c1:9e:dc:2d:74:5a:cc:2b:ca:82
+ 0a:5d:3b:82:93:31:ce:12:bd:5b:7d:54:87:c0:8a:0e
+ df:86:d6:6f:62:ca:4a:41:5f:6c:8e:cb:ac:6e:37:c0
+ b8:26:20:c3:59:37:ce:1f:e7:eb:a5:08:8a:b0:96:f3
+ e0:3d:fc:66:c4:6b:66:14:91:76:2c:22:e4:6a:56:20
+ 41:51:6a:77:f1:bf:4c:5b:e8:fa:af:41:09:a8:77:5a
+ 6a:66:6d:12:83:54:c1:e8:ff:b7:3a:db:9f:46:e2:ce
+ d8:60:a8:03:23:78:41:5f:fb:ea:16:62:20:24:8d:8b
+ 49:64:e4:cb:ca:83:e8:c4:60:97:fb:bf:e7:dc:2c:10
+ ba:03:67:76:ea:4d:00:6c:06:f8:d2:83:fb:26:fe:dc
+ e1:
+
+exp1:
+ 00:db:9c:94:f1:ea:7b:4b:05:f8:3e:ea:c8:7a:99:fc
+ d2:b0:85:2a:b9:48:be:a7:71:2d:74:eb:b8:25:fd:a2
+ 7a:60:38:96:64:b9:ef:6b:59:d0:40:e6:34:04:48:6d
+ 85:33:12:65:d1:cc:c9:63:58:24:58:e0:94:e7:9f:2b
+ a6:6a:bd:70:25:70:5b:cf:87:df:15:02:46:1d:d3:81
+ 3d:e9:75:6c:78:ba:ca:c6:d0:f1:53:1b:59:8e:b1:57
+ 28:ef:95:e5:67:ae:a3:47:dc:b1:db:5b:51:aa:14:df
+ d7:ef:74:6a:6a:5d:07:54:b3:b3:de:90:a7:47:a4:45
+ 8a:81:64:d0:0b:64:85:ed:73:23:bb:49:08:c5:44:87
+ 17:cd:9f:a6:17:40:8d:58:d4:e5:6a:75:04:0e:aa:a2
+ 75:04:29:01:4c:12:e5:15:47:ae:76:90:98:ce:78:82
+ 1f:fc:7e:b3:95:e0:b3:17:e6:25:cf:b4:8d:f9:cb:79
+ 01:
+
+exp2:
+ 00:ad:d1:a9:99:e9:6a:be:8f:ab:f4:78:81:17:90:71
+ 66:66:ee:a2:0a:65:01:db:c2:a4:90:4f:37:ef:fe:83
+ ec:75:1f:b1:18:ae:02:1e:77:f2:5d:91:9d:8e:1b:04
+ 1c:85:c2:48:84:71:c1:8f:36:1a:bd:61:9a:74:53:8e
+ 94:be:b9:a0:3d:31:d7:9a:7e:41:40:5f:70:3e:3f:5c
+ b9:54:e5:be:90:e4:54:a0:b7:23:b3:65:7b:83:77:bb
+ 97:9c:50:6e:ec:38:7d:60:a5:17:a5:99:a3:b4:e4:b5
+ b9:dd:81:59:0e:91:cf:2a:3b:2b:09:a0:98:5a:6a:7b
+ 31:2a:e1:3c:f8:c4:fe:b3:b2:d1:02:e3:d9:c4:18:e0
+ 07:b3:73:05:e1:f6:17:c7:34:fc:74:b3:eb:93:17:49
+ 8b:82:75:cb:f5:b7:36:69:7c:87:8c:2a:e0:07:8b:ff
+ d4:76:04:e0:da:7e:a2:85:33:55:fb:81:97:37:5c:13
+ dd:
+
+
+Public Key ID: C5:43:DA:C5:F5:E5:8C:7A:A3:6D:AC:33:0E:19:BD:5F:67:9E:04:61
+Public key's random art:
++--[ RSA 3072]----+
+| ..... .|
+| = .. =.|
+| . = E. +|
+| . o... |
+| S . o.o |
+| o *.. |
+| o o +.+|
+| .o+.+o|
+| .oo...|
++-----------------+
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIG5QIBAAKCAYEA8nNWVoZwi7fYKSYxm+lidTbMQEHh9pLXV8P1N2FDwqhNc6Z7
+1VqQw6gIDyzxBjZf3ldyPb6xAcxikvk2XCxVGqDaP7E1rfnCDSqxcgLGr1/TlRH3
+fFMFPqzMgs0GbDoKi7WuhcNMH1yIRk4uPVSUY3IclcE9sNvMpNVY77c9tYeLyoLg
+G8A2ljlSjbHXDmR8E1C+WcOvjFKQunpv29zIOvfp3Wuw0g3C6E26RyvYOnNNq6bm
+DHXdyIkxYNPwxyfBDGq/WhnrFqQTyEqulVLVVIpK+3fIdtmH/4OpOwxzKM0q2k9C
+zL+AI1JqlFoePeIKYQYAOssUBwB0VBDbhyo8f7txBs6OB1phPcmbkAo2bJfL01UT
+315omqlGWjvvDRjDEeRAfXnWu/UVLIs1MNn09l2+fKwgZyOZIQEk5gGgb+xO7pZp
+5W1IuLxB1DMatQjYK1L1MG8KUebovTyumAj8kOaCJaqa+EWcPvsH2wJbzp7JZV7x
+AMnNQGLHHccY9Iv9AgMBAAECggGAY6qwOl+H0pff34KY8Cvv0pmVO3EZ7+ALcEPZ
+AUwVq+a9+CXfUCSr0BK6RWrHJjOiE2fFScajQ0b+2sZh52A+F/U54ub5VyyN7hW3
+3lNv09ZDx0scftouFMa6R6b61fDCNw6X0Nso5teGGci3z3R+j6bwQ0uuDY89wCEI
+L3sXfhFbkQNeF2pbxkOIQUFzU7JRIyuVJJeCCeBDKLV+WFaZZUxWsjQ7+w23KwIQ
+6oMGn3iY3FB+z26AnphvWQunNmeLcq11lpwTpI4XB21FMLFVA4FlawLhMP6ca2OA
+rp1HsTPqthxtFC//KXHinN1AYjQERD2NcWvR6o1GYzcSJo+UHPVq0WZ/qdbdWSd5
+zuqts0diufYcNgrA/vP24cKGEpf58n5itDM+rUMFlR0U/r52xkQ4gKQlCFtcdk6p
+vap/8QWLSYGgQEsamNHJz5jhunES/B9TqldcZTrgciTVjychnPy21vfIB1zCQl3L
+ur8N8hObB2tzrhvwtxpq/SDPsnIBAoHBAP4UzzGg2OD1STUiLBQTqlXWJpLC+mMC
+ct3RBdEPsKSu5A6ZoDXjhCQGqidNzm8zbYqWPlS9UZLpP5vybp19Hi/hEbzbNMgv
+qwfuSl2WBVQcSPA8g5k6n13+MUgMswyr41wt5wZDkVxiIXYKTwDso5WFsP47YYsH
+xyG7tO8N0WcB3b2b6FbryiKDweiJO/oXI+ne/WIEcx8qiWbX0RaZf5ig4MKbESIj
+uVXLoEvrgaSogl3gCssZ/Rhd4hfMEysZgQKBwQD0SAsWOOjZlH44KXHUKvp8zdi1
+0tvRpj8fPzkv8q89rozJ/QEyg89I9PUllT8Kg5AhdWBSAZpeldLtTG6M+ZOaQCS1
+kevmtJZqalEbmxj9JMjDaFLjVfUj4JdNS0vNgwS54XC2TEKmoAwuDfChwAQIVw/a
+Dg7uMnwg5gPuNUEiAbDzbu4N15Ed7ZjU7+YD8TmW3aAfbDo92dKs8BNzMc+x+xPT
+VVUbbL05SeB6t+/sPVzdfb+gEWmPZvxFKbMFGH0CgcEA25yU8ep7SwX4PurIepn8
+0rCFKrlIvqdxLXTruCX9onpgOJZkue9rWdBA5jQESG2FMxJl0czJY1gkWOCU558r
+pmq9cCVwW8+H3xUCRh3TgT3pdWx4usrG0PFTG1mOsVco75XlZ66jR9yx21tRqhTf
+1+90ampdB1Szs96Qp0ekRYqBZNALZIXtcyO7SQjFRIcXzZ+mF0CNWNTlanUEDqqi
+dQQpAUwS5RVHrnaQmM54gh/8frOV4LMX5iXPtI35y3kBAoHBAK3RqZnpar6Pq/R4
+gReQcWZm7qIKZQHbwqSQTzfv/oPsdR+xGK4CHnfyXZGdjhsEHIXCSIRxwY82Gr1h
+mnRTjpS+uaA9MdeafkFAX3A+P1y5VOW+kORUoLcjs2V7g3e7l5xQbuw4fWClF6WZ
+o7TktbndgVkOkc8qOysJoJhaansxKuE8+MT+s7LRAuPZxBjgB7NzBeH2F8c0/HSz
+65MXSYuCdcv1tzZpfIeMKuAHi//UdgTg2n6ihTNV+4GXN1wT3QKBwQCbC2bX/t1p
+0ppb1U428MhnTmj/1SGhklAnl0dugj2zxYfSwBUJwZ7cLXRazCvKggpdO4KTMc4S
+vVt9VIfAig7fhtZvYspKQV9sjsusbjfAuCYgw1k3zh/n66UIirCW8+A9/GbEa2YU
+kXYsIuRqViBBUWp38b9MW+j6r0EJqHdaamZtEoNUwej/tzrbn0bizthgqAMjeEFf
+++oWYiAkjYtJZOTLyoPoxGCX+7/n3CwQugNndupNAGwG+NKD+yb+3OE=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/travis/trusty.supp b/tests/travis/trusty.supp
new file mode 100644
index 0000000..b490807
--- /dev/null
+++ b/tests/travis/trusty.supp
@@ -0,0 +1,10 @@
+{
+ gnu_libc_memerr
+ Memcheck:Free
+ fun:free
+ fun:__libc_freeres
+ fun:_vgnU_freeres
+ fun:__run_exit_handlers
+ fun:exit
+ fun:(below main)
+}
diff --git a/tests/udp-msgreduc-orgmsg-vg.sh b/tests/udp-msgreduc-orgmsg-vg.sh
new file mode 100755
index 0000000..603ba27
--- /dev/null
+++ b/tests/udp-msgreduc-orgmsg-vg.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# check if valgrind violations occur. Correct output is not checked.
+# added 2011-03-01 by Rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[udp-msgreduc-orgmsg-vg.sh\]: testing msg reduction via udp, with org message
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$ModLoad ../plugins/imudp/.libs/imudp
+$UDPServerRun '$TCPFLOOD_PORT'
+$RepeatedMsgReduction on
+$RepeatedMsgContainsOriginalMsg on
+
+$template outfmt,"%msg:F,58:2%\n"
+*.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+tcpflood -t 127.0.0.1 -m 4 -r -Tudp -M "\"<133>2011-03-01T11:22:12Z host tag msgh ...\""
+tcpflood -t 127.0.0.1 -m 1 -r -Tudp -M "\"<133>2011-03-01T11:22:12Z host tag msgh ...x\""
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown_vg
+if [ "$RSYSLOGD_EXIT" -eq "10" ]
+then
+ echo "udp-msgreduc-orgmsg-vg.sh FAILED"
+ exit 1
+fi
+exit_test
diff --git a/tests/udp-msgreduc-vg.sh b/tests/udp-msgreduc-vg.sh
new file mode 100755
index 0000000..1cfd6a1
--- /dev/null
+++ b/tests/udp-msgreduc-vg.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# check if valgrind violations occur. Correct output is not checked.
+# added 2011-03-01 by Rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+echo ===============================================================================
+echo \[udp-msgreduc-vg.sh\]: testing imtcp multiple listeners
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$ModLoad ../plugins/imudp/.libs/imudp
+$UDPServerRun '$TCPFLOOD_PORT'
+$RepeatedMsgReduction on
+
+$template outfmt,"%msg:F,58:2%\n"
+*.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+#:msg, contains, "msgnum:" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+startup_vg
+tcpflood -t 127.0.0.1 -m 4 -r -Tudp -M "\"<133>2011-03-01T11:22:12Z host tag msgh ...\""
+tcpflood -t 127.0.0.1 -m 1 -r -Tudp -M "\"<133>2011-03-01T11:22:12Z host tag msgh ...x\""
+shutdown_when_empty # shut down rsyslogd when done processing messages
+wait_shutdown_vg
+if [ "$RSYSLOGD_EXIT" -eq "10" ]
+then
+ echo "udp-msgreduc-vg.sh FAILED"
+ exit 1
+fi
+exit_test
diff --git a/tests/unused_lookup_table-vg.sh b/tests/unused_lookup_table-vg.sh
new file mode 100755
index 0000000..fb49c89
--- /dev/null
+++ b/tests/unused_lookup_table-vg.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# test for ensuring clean destruction of lookup-table even when it is never used
+# added 2015-09-30 by singh.janmejay
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+skip_platform "FreeBSD" "This test currently does not work on FreeBSD"
+generate_conf
+add_conf '
+lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl")
+
+template(name="outfmt" type="string" string="- %msg%\n")
+
+action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl
+startup_vg
+injectmsg 0 1
+shutdown_when_empty
+wait_shutdown_vg
+check_exit_vg
+content_check "msgnum:00000000:"
+exit_test
+
+# the test actually expects clean destruction of lookup_table
+# when lookup_table is loaded, it can either be:
+# - used (clean destruct covered by another test)
+# - not-used (this test ensures its destroyed cleanly)
diff --git a/tests/urlencode.py b/tests/urlencode.py
new file mode 100755
index 0000000..661314f
--- /dev/null
+++ b/tests/urlencode.py
@@ -0,0 +1,14 @@
+# call this via "python[3] script name"
+# a small url encoder for testbench purposes
+# written 2018-11-05 by Rainer Gerhards
+# part of the rsyslog testbench, released under ASL 2.0
+import sys
+try:
+ from urllib.parse import quote_plus
+except ImportError:
+ from urllib import quote_plus
+
+if len(sys.argv) != 2:
+ print("ERROR: urlencode needs exactly one string as argument")
+ sys.exit(1)
+print(quote_plus(sys.argv[1]))
diff --git a/tests/uxsock_simple.sh b/tests/uxsock_simple.sh
new file mode 100755
index 0000000..af97698
--- /dev/null
+++ b/tests/uxsock_simple.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+# 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
+. ${srcdir:=.}/diag.sh init
+check_command_available timeout
+
+uname
+if [ $(uname) = "FreeBSD" ] ; then
+ echo "This test currently does not work on FreeBSD."
+ exit 77
+fi
+
+# create the pipe and start a background process that copies data from
+# it to the "regular" work file
+generate_conf
+add_conf '
+$MainMsgQueueTimeoutShutdown 10000
+
+$ModLoad ../plugins/omuxsock/.libs/omuxsock
+$template outfmt,"%msg:F,58:2%\n"
+$OMUXSockSocket '$RSYSLOG_DYNNAME'-testbench-dgram-uxsock
+:msg, contains, "msgnum:" :omuxsock:;outfmt
+'
+timeout 30s ./uxsockrcvr -s$RSYSLOG_DYNNAME-testbench-dgram-uxsock -o $RSYSLOG_OUT_LOG -t 60 &
+BGPROCESS=$!
+echo background uxsockrcvr process id is $BGPROCESS
+
+# now do the usual run
+startup
+# 10000 messages should be enough
+injectmsg 0 10000
+shutdown_when_empty # shut down rsyslogd when done processing messages
+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
+seq_check 0 9999
+exit_test
diff --git a/tests/uxsockrcvr.c b/tests/uxsockrcvr.c
new file mode 100644
index 0000000..0d61ce9
--- /dev/null
+++ b/tests/uxsockrcvr.c
@@ -0,0 +1,192 @@
+/* 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)
+ * -t timeout in seconds (default 60)
+ *
+ * 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>
+#if defined(_AIX)
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <sys/socket.h>
+ #include <sys/socketvar.h>
+#else
+ #include <getopt.h>
+#endif
+#include <sys/un.h>
+#include <netdb.h>
+#include <poll.h>
+#include <errno.h>
+#if defined(__FreeBSD__)
+#include <sys/socket.h>
+#endif
+
+#define DFLT_TIMEOUT 60
+
+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;
+ int timeout = DFLT_TIMEOUT;
+ FILE *fp = stdout;
+ unsigned char data[128*1024];
+ struct sockaddr_un addr; /* address of server */
+ struct sockaddr from;
+ socklen_t fromlen;
+ struct pollfd fds[1];
+
+ if(argc < 2) {
+ fprintf(stderr, "error: too few arguments!\n");
+ usage();
+ }
+
+ while((opt = getopt(argc, argv, "s:o:lt:")) != 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;
+ case 't':
+ timeout = atoi(optarg);
+ break;
+ default:usage();
+ }
+ }
+
+ timeout = timeout * 1000;
+
+ 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);
+ }
+
+ fds[0].fd = sock;
+ fds[0].events = POLLIN;
+
+ /* 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 = poll(fds, 1, timeout);
+ if(rlen == -1) {
+ perror("uxsockrcvr : poll\n");
+ exit(1);
+ } else if(rlen == 0) {
+ fprintf(stderr, "Socket timed out - nothing to receive\n");
+ exit(1);
+ } else {
+ 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;
+}
diff --git a/tests/validation-run.sh b/tests/validation-run.sh
new file mode 100755
index 0000000..8ecad6b
--- /dev/null
+++ b/tests/validation-run.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# check if the configuration test run detects invalid config files.
+#
+# Part of the testbench for rsyslog.
+#
+# Copyright 2009-2018 Rainer Gerhards and Adiscon GmbH.
+#
+# This file is part of rsyslog.
+# Released under ASL 2.0
+echo \[validation-run.sh\]: testing configuration validation
+echo "testing a failed configuration verification run"
+../tools/rsyslogd -u2 -N1 -f$srcdir/testsuites/invalid.conf -M../runtime/.libs:../.libs
+if [ $? -ne 1 ]; then
+ echo "after test 1: return code ne 1"
+ exit 1
+fi
+echo testing a valid config verification run
+../tools/rsyslogd -u2 -N1 -f$srcdir/testsuites/valid.conf -M../runtime/.libs:../.libs
+if [ $? -ne 0 ]; then
+ echo "after test 2: return code ne 0"
+ exit 1
+fi
+echo testing empty config file
+../tools/rsyslogd -u2 -N1 -f/dev/null -M../runtime/.libs:../.libs
+if [ $? -ne 1 ]; then
+ echo "after test 3: return code ne 1"
+ exit 1
+fi
+echo SUCCESS: validation run tests
diff --git a/tests/variable_leading_underscore.sh b/tests/variable_leading_underscore.sh
new file mode 100755
index 0000000..3d80864
--- /dev/null
+++ b/tests/variable_leading_underscore.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 2015 Red Hat, Inc.
+# This file is part of the rsyslog project, released under ASL 2.0
+# The configuration test should pass because we now support leading
+# underscores in variable names.
+. ${srcdir:=.}/diag.sh init
+../tools/rsyslogd -C -N1 -f$srcdir/testsuites/variable_leading_underscore.conf -M../runtime/.libs:../.libs
+if [ $? -ne 0 ]; then
+ echo "Error: config check fail"
+ exit 1
+fi
+exit_test
+
diff --git a/tests/with_space.mmdb b/tests/with_space.mmdb
new file mode 100644
index 0000000..85120ba
--- /dev/null
+++ b/tests/with_space.mmdb
Binary files differ
diff --git a/tests/wr_large_async.sh b/tests/wr_large_async.sh
new file mode 100755
index 0000000..7a94f83
--- /dev/null
+++ b/tests/wr_large_async.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# This tests async writing large data records. We use up to 10K
+# record size.
+# added 2010-03-10 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=4000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+$MaxMessageSize 10k
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n"
+template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'") # trick to use relative path names!
+$OMFileFlushInterval 2
+$OMFileIOBufferSize 256k
+$OMFileAsyncWriting on
+local0.* ?dynfile;outfmt
+'
+startup
+# send 4000 messages of 10.000bytes plus header max, randomized
+tcpflood -m$NUMMESSAGES -r -d10000 -P129
+shutdown_when_empty
+wait_shutdown
+export SEQ_CHECK_OPTIONS=-E
+seq_check
+exit_test
diff --git a/tests/wr_large_sync.sh b/tests/wr_large_sync.sh
new file mode 100755
index 0000000..53758b0
--- /dev/null
+++ b/tests/wr_large_sync.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# This tests async writing large data records. We use up to 10K
+# record size.
+
+# added 2010-03-10 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=4000
+export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
+generate_conf
+add_conf '
+$MaxMessageSize 10k
+
+module(load="../plugins/imtcp/.libs/imtcp")
+input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n"
+template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'") # trick to use relative path names!
+$OMFileIOBufferSize 256k
+$OMFileAsyncWriting off
+local0.* ?dynfile;outfmt
+'
+startup
+# send 4000 messages of 10.000bytes plus header max, randomized
+tcpflood -m$NUMMESSAGES -r -d10000 -P129
+shutdown_when_empty
+wait_shutdown
+export SEQ_CHECK_OPTIONS=-E
+seq_check
+exit_test
diff --git a/tests/wtpShutdownAll-assertionFailure.sh b/tests/wtpShutdownAll-assertionFailure.sh
new file mode 100755
index 0000000..2d15a78
--- /dev/null
+++ b/tests/wtpShutdownAll-assertionFailure.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# add 2018-04-19 by Pascal Withopf, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+generate_conf
+add_conf '
+$AbortOnUncleanConfig on
+$LocalHostName wtpshutdownall
+$PreserveFQDN on
+
+global(
+ workDirectory="'${RSYSLOG_DYNNAME}'.spool"
+)
+
+module(load="../plugins/mmjsonparse/.libs/mmjsonparse")
+module(load="../plugins/impstats/.libs/impstats" interval="300"
+ resetCounters="on" format="cee" ruleset="metrics-impstat" log.syslog="on")
+
+ruleset(name="metrics-impstat" queue.type="Direct"){
+ action(type="omfile" file="'$RSYSLOG_DYNNAME'.spool/stats.log")
+}
+'
+startup
+shutdown_when_empty
+wait_shutdown
+
+# This test only checks that rsyslog does not abort
+# so we don't need to check for output.
+
+exit_test
diff --git a/tests/zstd-vg.sh b/tests/zstd-vg.sh
new file mode 100755
index 0000000..e9b11e2
--- /dev/null
+++ b/tests/zstd-vg.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+export USE_VALGRIND="YES"
+export NUMMESSAGES=10000 # valgrind is pretty slow, so we need to user lower nbr of msgs
+source ${srcdir:-.}/zstd.sh
diff --git a/tests/zstd.sh b/tests/zstd.sh
new file mode 100755
index 0000000..a109644
--- /dev/null
+++ b/tests/zstd.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# This tests writing large data records in zst mode. We use up to 10K
+# record size.
+#
+# added 2022-06-21 by Rgerhards
+#
+# This file is part of the rsyslog project, released under ASL 2.0
+. ${srcdir:=.}/diag.sh init
+export NUMMESSAGES=${NUMMESSAGES:-50000}
+export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check
+generate_conf
+# Note: we right now use the non-compressed file as indicator for "processing complete"
+#export SEQ_CHECK_FILE=$RSYSLOG_OUT_LOG.zst
+add_conf '
+$MaxMessageSize 10k
+$MainMsgQueueTimeoutShutdown 10000
+
+module(load="builtin:omfile" compression.driver="zstd" compression.zstd.workers="5")
+module(load="../plugins/imptcp/.libs/imptcp")
+input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n")
+local0.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'.zst" template="outfmt"
+ zipLevel="20" iobuffersize="64k" veryRobustZIP="off")
+local0.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt")
+'
+# rgerhards, 2019-08-14: Note: veryRobustZip may need to be "on". Do this if the test
+# still prematurely terminates. In that case it is likely that gunzip got confused
+# by the missing zip close record. My initial testing shows that while gunzip emits an
+# error message, everything is properly extracted. Only stressed CI runs will show how
+# it works in reality.
+startup
+assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port
+tcpflood -m$NUMMESSAGES -r -d10000 -P129
+shutdown_when_empty
+wait_shutdown
+seq_check 0 $((NUMMESSAGES - 1)) -E
+exit_test