mirror of
https://github.com/rsyslog/rsyslog.git
synced 2026-04-23 12:38:12 +02:00
testbench: queue timeouts via imdiag module params; yaml-only mode fixes and docs
- imdiag: add 5 module-scope config params to control key queue timeouts (mainmsgqueuetimeoutshutdown, mainmsgqueuetimeoutenqueue, inputshutdowntimeout, defaultactionqueuetimeoutshutdown, defaultactionqueuetimeoutenqueue); these replace per-test legacy $MainMsg* directives and eliminate races on slow machines (Solaris) - imdiag: add assert(0) for unhandled params in setModCnf/newInpInst - imdiag: modExit sets abortTimeout=-1 after joining timeoutGuard thread to prevent double-cancel if resetConfigVariables runs afterwards - diag.sh: generate_conf --yaml-only flag for YAML-only test mode - diag.sh: yaml preamble uses new imdiag module params - diag.sh: add RSTB_MAIN_Q_TO_ENQUEUE separate from action queue var - diag.sh: restore .started with instance-ID suffix for content_check - diag.sh: wait_startup() uses imdiag port file for startup detection - tests: add yaml-basic-yamlonly.sh smoke test - doc: 6 new reference pages for new imdiag params (with meta blocks) - doc: imdiag.rst updated with new module-scope params table - doc: dev_testbench.rst corrected .started vs port-file description Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
b2caab060e
commit
5a78def249
@ -453,8 +453,14 @@ EXTRA_DIST = \
|
||||
source/rainerscript/variable_property_types.rst \
|
||||
source/reference/parameters/im3195-input3195listenport.rst \
|
||||
source/reference/parameters/imdiag-aborttimeout.rst \
|
||||
source/reference/parameters/imdiag-defaultactionqueuetimeoutenqueue.rst \
|
||||
source/reference/parameters/imdiag-defaultactionqueuetimeoutshutdown.rst \
|
||||
source/reference/parameters/imdiag-injectdelaymode.rst \
|
||||
source/reference/parameters/imdiag-inputshutdowntimeout.rst \
|
||||
source/reference/parameters/imdiag-listenportfilename.rst \
|
||||
source/reference/parameters/imdiag-listenportfilename-module.rst \
|
||||
source/reference/parameters/imdiag-mainmsgqueuetimeoutenqueue.rst \
|
||||
source/reference/parameters/imdiag-mainmsgqueuetimeoutshutdown.rst \
|
||||
source/reference/parameters/imdiag-maxsessions.rst \
|
||||
source/reference/parameters/imdiag-serverinputname.rst \
|
||||
source/reference/parameters/imdiag-serverrun.rst \
|
||||
|
||||
@ -37,6 +37,30 @@ Module Parameters
|
||||
- .. include:: ../../reference/parameters/imdiag-aborttimeout.rst
|
||||
:start-after: .. summary-start
|
||||
:end-before: .. summary-end
|
||||
* - :ref:`param-imdiag-listenportfilename-module`
|
||||
- .. include:: ../../reference/parameters/imdiag-listenportfilename-module.rst
|
||||
:start-after: .. summary-start
|
||||
:end-before: .. summary-end
|
||||
* - :ref:`param-imdiag-mainmsgqueuetimeoutshutdown`
|
||||
- .. include:: ../../reference/parameters/imdiag-mainmsgqueuetimeoutshutdown.rst
|
||||
:start-after: .. summary-start
|
||||
:end-before: .. summary-end
|
||||
* - :ref:`param-imdiag-mainmsgqueuetimeoutenqueue`
|
||||
- .. include:: ../../reference/parameters/imdiag-mainmsgqueuetimeoutenqueue.rst
|
||||
:start-after: .. summary-start
|
||||
:end-before: .. summary-end
|
||||
* - :ref:`param-imdiag-inputshutdowntimeout`
|
||||
- .. include:: ../../reference/parameters/imdiag-inputshutdowntimeout.rst
|
||||
:start-after: .. summary-start
|
||||
:end-before: .. summary-end
|
||||
* - :ref:`param-imdiag-defaultactionqueuetimeoutshutdown`
|
||||
- .. include:: ../../reference/parameters/imdiag-defaultactionqueuetimeoutshutdown.rst
|
||||
:start-after: .. summary-start
|
||||
:end-before: .. summary-end
|
||||
* - :ref:`param-imdiag-defaultactionqueuetimeoutenqueue`
|
||||
- .. include:: ../../reference/parameters/imdiag-defaultactionqueuetimeoutenqueue.rst
|
||||
:start-after: .. summary-start
|
||||
:end-before: .. summary-end
|
||||
* - :ref:`param-imdiag-injectdelaymode`
|
||||
- .. include:: ../../reference/parameters/imdiag-injectdelaymode.rst
|
||||
:start-after: .. summary-start
|
||||
@ -96,10 +120,49 @@ ephemeral port, and records the chosen port for the testbench to read.
|
||||
listenPortFileName="/var/run/rsyslog/imdiag.port"
|
||||
serverRun="0")
|
||||
|
||||
YAML-only testbench configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In YAML-only mode the testbench preamble uses the ``testbench_modules:``
|
||||
key (an alias for ``modules:`` reserved for testbench infrastructure) so
|
||||
that it does not conflict with the test's own ``modules:`` section.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
version: 2
|
||||
|
||||
global:
|
||||
debug.abortOnProgramError: "on"
|
||||
|
||||
testbench_modules:
|
||||
- load: "../plugins/imdiag/.libs/imdiag"
|
||||
listenportfilename: "test.imdiag.port"
|
||||
aborttimeout: "580"
|
||||
mainmsgqueuetimeoutshutdown: "10000"
|
||||
mainmsgqueuetimeoutenqueue: "30000"
|
||||
inputshutdowntimeout: "60000"
|
||||
defaultactionqueuetimeoutshutdown: "20000"
|
||||
defaultactionqueuetimeoutenqueue: "30000"
|
||||
|
||||
modules:
|
||||
- load: "../plugins/imtcp/.libs/imtcp"
|
||||
|
||||
inputs:
|
||||
- type: imdiag
|
||||
port: "0"
|
||||
- type: imtcp
|
||||
port: "0"
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
../../reference/parameters/imdiag-aborttimeout
|
||||
../../reference/parameters/imdiag-listenportfilename-module
|
||||
../../reference/parameters/imdiag-mainmsgqueuetimeoutshutdown
|
||||
../../reference/parameters/imdiag-mainmsgqueuetimeoutenqueue
|
||||
../../reference/parameters/imdiag-inputshutdowntimeout
|
||||
../../reference/parameters/imdiag-defaultactionqueuetimeoutshutdown
|
||||
../../reference/parameters/imdiag-defaultactionqueuetimeoutenqueue
|
||||
../../reference/parameters/imdiag-injectdelaymode
|
||||
../../reference/parameters/imdiag-maxsessions
|
||||
../../reference/parameters/imdiag-listenportfilename
|
||||
|
||||
@ -1,20 +1,191 @@
|
||||
writing rsyslog tests
|
||||
Writing rsyslog Tests
|
||||
=====================
|
||||
|
||||
The rsyslog testbench is executed via `make check` or `make distcheck`. For details, on
|
||||
these modes, see the GNU autotools documentation. The most important thing is that
|
||||
the `make distcheck` test execution environment is considerably different from its
|
||||
`make check` counterpart. The rsyslog testbench is crafted to handle both cases and
|
||||
does so with the (intensive) use of environment variables.
|
||||
The rsyslog testbench is executed via ``make check`` or ``make distcheck``. For details
|
||||
on these modes, see the GNU autotools documentation. The most important thing is that
|
||||
the ``make distcheck`` test execution environment is considerably different from its
|
||||
``make check`` counterpart. The rsyslog testbench is crafted to handle both cases and
|
||||
does so with the intensive use of environment variables.
|
||||
|
||||
The rsyslog testbench aims to support parallel tests. This is not yet fully implemented,
|
||||
but we are working towards that goal. This has a number of implications/requirements:
|
||||
|
||||
* all file names, ports, etc need to be unique
|
||||
* the diag.sh framework supports auto-generation capabilities to support this:
|
||||
use `${RSYSLOG_DYNNAME}` a prefix for all files you generate. For the frequently
|
||||
used files, the framework already defines `${RSYSLOG_OUT_LOG}` and `${RSYSLOG_OUT_LOG2}`
|
||||
* All file names, ports, etc. need to be unique.
|
||||
* The ``diag.sh`` framework supports auto-generation capabilities to support this:
|
||||
use ``${RSYSLOG_DYNNAME}`` as a prefix for all files you generate. For the frequently
|
||||
used files, the framework already defines ``${RSYSLOG_OUT_LOG}`` and
|
||||
``${RSYSLOG_OUT_LOG2}``.
|
||||
|
||||
When writing new tests, it is in general advisable to copy an existing test and modify
|
||||
it. This also ensures you inherit the correct boilerplate and environment setup.
|
||||
|
||||
Test Modes
|
||||
----------
|
||||
|
||||
The testbench supports two configuration modes for rsyslogd:
|
||||
|
||||
RainerScript mode (default)
|
||||
The classic mode. ``generate_conf`` writes a ``.conf`` file using
|
||||
``module()`` / ``input()`` / ``global()`` v2 RainerScript syntax. Legacy
|
||||
``$Directive`` syntax is still accepted but deprecated.
|
||||
|
||||
YAML-only mode
|
||||
Pure-YAML configuration. ``generate_conf --yaml-only`` writes a ``.yaml``
|
||||
file using the rsyslog v2 YAML loader. No RainerScript preamble is written.
|
||||
See `YAML-only mode`_ below.
|
||||
|
||||
Startup detection uses the imdiag port file in both modes. In RainerScript
|
||||
mode, rsyslogd's own messages (startup, shutdown, errors) are also captured to
|
||||
the instance's ``.started`` file via the syslogtag filter rule; tests may
|
||||
use that file for content checks. In YAML-only mode no ``.started`` file is
|
||||
written.
|
||||
|
||||
.. _yaml-only-mode:
|
||||
|
||||
YAML-only Mode
|
||||
--------------
|
||||
|
||||
Use ``generate_conf --yaml-only`` when a test must validate the YAML
|
||||
configuration loader or when you want to avoid any RainerScript entirely.
|
||||
|
||||
How It Works
|
||||
~~~~~~~~~~~~
|
||||
|
||||
1. ``generate_conf --yaml-only [instance]`` writes
|
||||
``${TESTCONF_NM}[instance].yaml`` containing:
|
||||
|
||||
- ``version: 2``
|
||||
- ``global:`` section with ``debug.abortOnProgramError: "on"`` (and
|
||||
``net.ipprotocol:`` if ``RSTB_FORCE_IPV4=1`` or ``RSTB_NET_IPPROTO`` is
|
||||
set)
|
||||
- ``testbench_modules:`` section that loads ``imdiag`` with all testbench
|
||||
parameters set (port file, abort timeout, queue/input timeouts)
|
||||
|
||||
The ``testbench_modules:`` key is recognised by rsyslogd as an alias for
|
||||
``modules:``. It is reserved for testbench infrastructure so it does not
|
||||
conflict with the test's own ``modules:`` section.
|
||||
|
||||
2. Tests add their own sections with ``add_yaml_conf``.
|
||||
3. Tests must call ``add_yaml_imdiag_input`` inside their ``inputs:`` section
|
||||
so that startup detection works.
|
||||
|
||||
Helper Functions
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
``generate_conf --yaml-only [instance]``
|
||||
Create the YAML preamble. Sets ``RSYSLOG_YAML_ONLY=1``.
|
||||
|
||||
``add_yaml_conf 'fragment' [instance]``
|
||||
Append a YAML fragment to ``${TESTCONF_NM}[instance].yaml``.
|
||||
|
||||
``add_yaml_imdiag_input [instance]``
|
||||
Append the imdiag ``inputs:`` entry inside an already-opened ``inputs:``
|
||||
block. **Required** in every yaml-only test for startup detection.
|
||||
|
||||
Startup detection
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Both RainerScript and yaml-only modes use the imdiag port file
|
||||
(``${RSYSLOG_DYNNAME}.imdiag[instance].port``) as the sole startup signal.
|
||||
``wait_startup`` polls for this file and fast-fails if rsyslogd exits before
|
||||
it appears. No ``.started`` marker file is used.
|
||||
|
||||
Queue and Input Timeouts
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Default testbench timeout values are set via the ``RSTB_*`` environment
|
||||
variables before ``generate_conf`` is called. The variables and their defaults
|
||||
are:
|
||||
|
||||
.. list-table::
|
||||
:widths: 40 20 40
|
||||
:header-rows: 1
|
||||
|
||||
* - Variable
|
||||
- Default (ms)
|
||||
- Controls
|
||||
* - ``RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT``
|
||||
- 10000
|
||||
- Main message queue shutdown timeout
|
||||
* - ``RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT``
|
||||
- 60000
|
||||
- Input shutdown timeout
|
||||
* - ``RSTB_ACTION_DEFAULT_Q_TO_SHUTDOWN``
|
||||
- 20000
|
||||
- Default action queue shutdown timeout
|
||||
* - ``RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE``
|
||||
- 30000
|
||||
- Default action queue enqueue timeout
|
||||
* - ``RSTB_MAIN_Q_TO_ENQUEUE``
|
||||
- 30000
|
||||
- Main message queue enqueue timeout
|
||||
|
||||
These are injected as ``imdiag`` module parameters at config-load time, so
|
||||
they take effect before any test-specific config is parsed. A test can
|
||||
override a value by setting the variable before calling ``generate_conf``.
|
||||
|
||||
If a test needs a *different* value for the main queue shutdown timeout (for
|
||||
example, a queue-persistence test that sets ``$MainMsgQueueTimeoutShutdown 1``
|
||||
in RainerScript), it should set the value in the configuration fragment itself.
|
||||
Legacy ``$MainMsgQueueTimeout*`` directives still work and override the
|
||||
imdiag-supplied defaults in RainerScript mode.
|
||||
|
||||
Limitations in YAML-only Mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The following RainerScript-specific features are not available in yaml-only
|
||||
mode:
|
||||
|
||||
* **Legacy ``$Directive`` syntax** -- not parsed by the YAML loader.
|
||||
* **``setvar_RS_HOSTNAME``** -- uses a RainerScript ``$template`` internally;
|
||||
it always runs against a RainerScript instance and its result is still
|
||||
available via ``$RS_HOSTNAME`` for yaml-only tests.
|
||||
|
||||
Example Test
|
||||
~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
#!/bin/bash
|
||||
. ${srcdir:=.}/diag.sh init
|
||||
require_plugin imtcp
|
||||
export NUMMESSAGES=100
|
||||
export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
|
||||
generate_conf --yaml-only
|
||||
|
||||
# Test-specific modules go in a standard modules: section.
|
||||
# Testbench infrastructure (imdiag) is already in testbench_modules:.
|
||||
add_yaml_conf 'modules:'
|
||||
add_yaml_conf ' - load: "../plugins/imtcp/.libs/imtcp"'
|
||||
add_yaml_conf ''
|
||||
add_yaml_conf 'templates:'
|
||||
add_yaml_conf ' - name: outfmt'
|
||||
add_yaml_conf ' type: string'
|
||||
add_yaml_conf ' string: "%msg:F,58:2%\n"'
|
||||
add_yaml_conf ''
|
||||
add_yaml_conf 'inputs:'
|
||||
add_yaml_imdiag_input # required -- provides startup detection
|
||||
add_yaml_conf " - type: imtcp"
|
||||
add_yaml_conf ' port: "0"'
|
||||
add_yaml_conf " listenPortFileName: \"${RSYSLOG_DYNNAME}.tcpflood_port\""
|
||||
add_yaml_conf ' ruleset: main'
|
||||
add_yaml_conf ''
|
||||
add_yaml_conf 'rulesets:'
|
||||
add_yaml_conf ' - name: main'
|
||||
add_yaml_conf ' script: |'
|
||||
add_yaml_conf " :msg, contains, \"msgnum:\" action(type=\"omfile\""
|
||||
add_yaml_conf " template=\"outfmt\" file=\"${RSYSLOG_OUT_LOG}\")"
|
||||
startup
|
||||
tcpflood -m $NUMMESSAGES
|
||||
shutdown_when_empty
|
||||
wait_shutdown
|
||||
seq_check
|
||||
exit_test
|
||||
|
||||
Naming and Registration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Name yaml-only tests ``yaml-<area>-yamlonly.sh`` (or append ``-yamlonly`` to
|
||||
an existing test name). Register them in ``tests/Makefile.am`` under
|
||||
``TESTS_LIBYAML`` so they are skipped on systems without libyaml.
|
||||
|
||||
When writing new tests, it is in general advisable to copy an existing test and change
|
||||
it. This also helps you get requirements files.
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
.. _param-imdiag-defaultactionqueuetimeoutenqueue:
|
||||
.. _imdiag.parameter.module.defaultactionqueuetimeoutenqueue:
|
||||
|
||||
.. meta::
|
||||
:description: Reference for the imdiag defaultActionQueueTimeoutEnqueue module parameter.
|
||||
:keywords: rsyslog, imdiag, defaultactionqueuetimeoutenqueue, testbench, timeout, action queue
|
||||
|
||||
DefaultActionQueueTimeoutEnqueue
|
||||
=================================
|
||||
|
||||
.. index::
|
||||
single: imdiag; DefaultActionQueueTimeoutEnqueue
|
||||
|
||||
.. summary-start
|
||||
|
||||
Sets the default action queue enqueue timeout at config load time.
|
||||
|
||||
.. summary-end
|
||||
|
||||
This parameter applies to :doc:`../../configuration/modules/imdiag`.
|
||||
|
||||
:Name: DefaultActionQueueTimeoutEnqueue
|
||||
:Scope: module
|
||||
:Type: integer (milliseconds)
|
||||
:Default: 30000
|
||||
:Required?: no
|
||||
:Introduced: 8.x
|
||||
|
||||
Description
|
||||
-----------
|
||||
Sets ``globals.actq_dflt_toEnq`` — the default enqueue timeout for action
|
||||
queues created after this point — at config-load time. This only affects
|
||||
action queues that do not specify their own timeout. When an action queue is
|
||||
full, a producer waits up to this duration before dropping the message.
|
||||
|
||||
.. note::
|
||||
This parameter affects action queues created *after* the module is
|
||||
loaded. Existing queues are unaffected.
|
||||
|
||||
Override per-test via ``RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE`` before
|
||||
``generate_conf``.
|
||||
|
||||
Module usage
|
||||
------------
|
||||
|
||||
.. code-block:: rsyslog
|
||||
|
||||
module(load="imdiag" defaultActionQueueTimeoutEnqueue="30000")
|
||||
|
||||
YAML usage
|
||||
----------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
testbench_modules:
|
||||
- load: "../plugins/imdiag/.libs/imdiag"
|
||||
defaultactionqueuetimeoutenqueue: "30000"
|
||||
|
||||
See also
|
||||
--------
|
||||
See also :doc:`../../configuration/modules/imdiag`.
|
||||
@ -0,0 +1,61 @@
|
||||
.. _param-imdiag-defaultactionqueuetimeoutshutdown:
|
||||
.. _imdiag.parameter.module.defaultactionqueuetimeoutshutdown:
|
||||
|
||||
.. meta::
|
||||
:description: Reference for the imdiag defaultActionQueueTimeoutShutdown module parameter.
|
||||
:keywords: rsyslog, imdiag, defaultactionqueuetimeoutshutdown, testbench, timeout, action queue
|
||||
|
||||
DefaultActionQueueTimeoutShutdown
|
||||
==================================
|
||||
|
||||
.. index::
|
||||
single: imdiag; DefaultActionQueueTimeoutShutdown
|
||||
|
||||
.. summary-start
|
||||
|
||||
Sets the default action queue shutdown timeout at config load time.
|
||||
|
||||
.. summary-end
|
||||
|
||||
This parameter applies to :doc:`../../configuration/modules/imdiag`.
|
||||
|
||||
:Name: DefaultActionQueueTimeoutShutdown
|
||||
:Scope: module
|
||||
:Type: integer (milliseconds)
|
||||
:Default: 20000
|
||||
:Required?: no
|
||||
:Introduced: 8.x
|
||||
|
||||
Description
|
||||
-----------
|
||||
Sets ``globals.actq_dflt_toQShutdown`` — the default shutdown timeout for
|
||||
action queues created after this point — at config-load time. This only
|
||||
affects action queues that do not specify their own timeout. The testbench
|
||||
uses this to ensure action queues drain cleanly under test conditions.
|
||||
|
||||
.. note::
|
||||
This parameter affects action queues created *after* the module is
|
||||
loaded. Existing queues are unaffected.
|
||||
|
||||
Override per-test via ``RSTB_ACTION_DEFAULT_Q_TO_SHUTDOWN`` before
|
||||
``generate_conf``.
|
||||
|
||||
Module usage
|
||||
------------
|
||||
|
||||
.. code-block:: rsyslog
|
||||
|
||||
module(load="imdiag" defaultActionQueueTimeoutShutdown="20000")
|
||||
|
||||
YAML usage
|
||||
----------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
testbench_modules:
|
||||
- load: "../plugins/imdiag/.libs/imdiag"
|
||||
defaultactionqueuetimeoutshutdown: "20000"
|
||||
|
||||
See also
|
||||
--------
|
||||
See also :doc:`../../configuration/modules/imdiag`.
|
||||
@ -0,0 +1,57 @@
|
||||
.. _param-imdiag-inputshutdowntimeout:
|
||||
.. _imdiag.parameter.module.inputshutdowntimeout:
|
||||
|
||||
.. meta::
|
||||
:description: Reference for the imdiag inputShutdownTimeout module parameter.
|
||||
:keywords: rsyslog, imdiag, inputshutdowntimeout, testbench, timeout, shutdown
|
||||
|
||||
InputShutdownTimeout
|
||||
====================
|
||||
|
||||
.. index::
|
||||
single: imdiag; InputShutdownTimeout
|
||||
|
||||
.. summary-start
|
||||
|
||||
Sets the input shutdown timeout at config load time.
|
||||
|
||||
.. summary-end
|
||||
|
||||
This parameter applies to :doc:`../../configuration/modules/imdiag`.
|
||||
|
||||
:Name: InputShutdownTimeout
|
||||
:Scope: module
|
||||
:Type: integer (milliseconds)
|
||||
:Default: 60000
|
||||
:Required?: no
|
||||
:Introduced: 8.x
|
||||
|
||||
Description
|
||||
-----------
|
||||
Sets ``globals.inputTimeoutShutdown`` — the time rsyslog allows each input
|
||||
plugin to stop during an orderly shutdown — at config-load time. The
|
||||
testbench uses this to ensure inputs have enough time to shut down cleanly
|
||||
under load, in both RainerScript and YAML-only modes.
|
||||
|
||||
Override per-test via ``RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT`` before
|
||||
``generate_conf``.
|
||||
|
||||
Module usage
|
||||
------------
|
||||
|
||||
.. code-block:: rsyslog
|
||||
|
||||
module(load="imdiag" inputShutdownTimeout="60000")
|
||||
|
||||
YAML usage
|
||||
----------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
testbench_modules:
|
||||
- load: "../plugins/imdiag/.libs/imdiag"
|
||||
inputshutdowntimeout: "60000"
|
||||
|
||||
See also
|
||||
--------
|
||||
See also :doc:`../../configuration/modules/imdiag`.
|
||||
@ -0,0 +1,59 @@
|
||||
.. _param-imdiag-listenportfilename-module:
|
||||
.. _imdiag.parameter.module.listenportfilename:
|
||||
|
||||
.. meta::
|
||||
:description: Reference for the imdiag listenPortFileName module-scope parameter.
|
||||
:keywords: rsyslog, imdiag, listenportfilename, testbench, port file, startup
|
||||
|
||||
ListenPortFileName (module scope)
|
||||
==================================
|
||||
|
||||
.. index::
|
||||
single: imdiag; ListenPortFileName (module)
|
||||
|
||||
.. summary-start
|
||||
|
||||
Path of the file to which imdiag writes its chosen TCP listen port number,
|
||||
set at module load time.
|
||||
|
||||
.. summary-end
|
||||
|
||||
This parameter applies to :doc:`../../configuration/modules/imdiag`.
|
||||
|
||||
:Name: ListenPortFileName
|
||||
:Scope: module
|
||||
:Type: string (file path)
|
||||
:Default: none
|
||||
:Required?: no (but recommended for testbench use)
|
||||
:Introduced: 8.x
|
||||
|
||||
Description
|
||||
-----------
|
||||
When set at module scope, ``ListenPortFileName`` specifies the file that
|
||||
imdiag will create and populate with its chosen listen port number after the
|
||||
TCP listener is ready. The testbench reads this file to discover the port
|
||||
without needing a fixed port number.
|
||||
|
||||
This is the module-scope version of the parameter. The same name can also
|
||||
be set at input scope via ``input(type="imdiag" listenPortFileName=...)``.
|
||||
|
||||
Module usage
|
||||
------------
|
||||
|
||||
.. code-block:: rsyslog
|
||||
|
||||
module(load="imdiag" listenPortFileName="/tmp/imdiag.port")
|
||||
|
||||
YAML usage
|
||||
----------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
testbench_modules:
|
||||
- load: "../plugins/imdiag/.libs/imdiag"
|
||||
listenportfilename: "/tmp/imdiag.port"
|
||||
|
||||
See also
|
||||
--------
|
||||
See also :doc:`../../configuration/modules/imdiag` and
|
||||
:ref:`param-imdiag-listenportfilename`.
|
||||
@ -0,0 +1,59 @@
|
||||
.. _param-imdiag-mainmsgqueuetimeoutenqueue:
|
||||
.. _imdiag.parameter.module.mainmsgqueuetimeoutenqueue:
|
||||
|
||||
.. meta::
|
||||
:description: Reference for the imdiag mainMsgQueueTimeoutEnqueue module parameter.
|
||||
:keywords: rsyslog, imdiag, mainmsgqueuetimeoutenqueue, testbench, timeout, queue
|
||||
|
||||
MainMsgQueueTimeoutEnqueue
|
||||
===========================
|
||||
|
||||
.. index::
|
||||
single: imdiag; MainMsgQueueTimeoutEnqueue
|
||||
|
||||
.. summary-start
|
||||
|
||||
Sets the main message queue enqueue timeout at config load time.
|
||||
|
||||
.. summary-end
|
||||
|
||||
This parameter applies to :doc:`../../configuration/modules/imdiag`.
|
||||
|
||||
:Name: MainMsgQueueTimeoutEnqueue
|
||||
:Scope: module
|
||||
:Type: integer (milliseconds)
|
||||
:Default: 30000
|
||||
:Required?: no
|
||||
:Introduced: 8.x
|
||||
|
||||
Description
|
||||
-----------
|
||||
Sets ``globals.mainQ.iMainMsgQtoEnq`` — the time a producer will wait when
|
||||
the main message queue is full before dropping the message — at config-load
|
||||
time. The testbench uses this to establish a safe default without relying on
|
||||
legacy ``$MainMsgQueueTimeoutEnqueue`` directives, which are not available in
|
||||
YAML-only mode.
|
||||
|
||||
Override per-test via ``RSTB_MAIN_Q_TO_ENQUEUE`` before
|
||||
``generate_conf``, or via a ``$MainMsgQueueTimeoutEnqueue`` directive in the
|
||||
RainerScript test fragment.
|
||||
|
||||
Module usage
|
||||
------------
|
||||
|
||||
.. code-block:: rsyslog
|
||||
|
||||
module(load="imdiag" mainMsgQueueTimeoutEnqueue="30000")
|
||||
|
||||
YAML usage
|
||||
----------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
testbench_modules:
|
||||
- load: "../plugins/imdiag/.libs/imdiag"
|
||||
mainmsgqueuetimeoutenqueue: "30000"
|
||||
|
||||
See also
|
||||
--------
|
||||
See also :doc:`../../configuration/modules/imdiag`.
|
||||
@ -0,0 +1,61 @@
|
||||
.. _param-imdiag-mainmsgqueuetimeoutshutdown:
|
||||
.. _imdiag.parameter.module.mainmsgqueuetimeoutshutdown:
|
||||
|
||||
.. meta::
|
||||
:description: Reference for the imdiag mainMsgQueueTimeoutShutdown module parameter.
|
||||
:keywords: rsyslog, imdiag, mainmsgqueuetimeoutshutdown, testbench, timeout, queue
|
||||
|
||||
MainMsgQueueTimeoutShutdown
|
||||
============================
|
||||
|
||||
.. index::
|
||||
single: imdiag; MainMsgQueueTimeoutShutdown
|
||||
|
||||
.. summary-start
|
||||
|
||||
Sets the main message queue shutdown timeout at config load time.
|
||||
|
||||
.. summary-end
|
||||
|
||||
This parameter applies to :doc:`../../configuration/modules/imdiag`.
|
||||
|
||||
:Name: MainMsgQueueTimeoutShutdown
|
||||
:Scope: module
|
||||
:Type: integer (milliseconds)
|
||||
:Default: 10000
|
||||
:Required?: no
|
||||
:Introduced: 8.x
|
||||
|
||||
Description
|
||||
-----------
|
||||
Sets ``globals.mainQ.iMainMsgQtoQShutdown`` — the time rsyslog waits for
|
||||
the main message queue to drain during an orderly shutdown — at config-load
|
||||
time. The testbench uses this to establish a safe default without relying on
|
||||
legacy ``$MainMsgQueueTimeoutShutdown`` directives, which are not available
|
||||
in YAML-only mode.
|
||||
|
||||
The value can be overridden per-test by setting the
|
||||
``RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT`` environment variable before calling
|
||||
``generate_conf``, or by writing a ``$MainMsgQueueTimeoutShutdown`` directive
|
||||
in the test's RainerScript configuration fragment (legacy directives apply
|
||||
after module params and therefore take precedence).
|
||||
|
||||
Module usage
|
||||
------------
|
||||
|
||||
.. code-block:: rsyslog
|
||||
|
||||
module(load="imdiag" mainMsgQueueTimeoutShutdown="10000")
|
||||
|
||||
YAML usage
|
||||
----------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
testbench_modules:
|
||||
- load: "../plugins/imdiag/.libs/imdiag"
|
||||
mainmsgqueuetimeoutshutdown: "10000"
|
||||
|
||||
See also
|
||||
--------
|
||||
See also :doc:`../../configuration/modules/imdiag`.
|
||||
@ -57,6 +57,7 @@
|
||||
#include "datetime.h"
|
||||
#include "ratelimit.h"
|
||||
#include "queue.h"
|
||||
#include "rsconf.h"
|
||||
#include "lookup.h"
|
||||
#include "net.h" /* for permittedPeers, may be removed when this is removed */
|
||||
#include "statsobj.h"
|
||||
@ -106,7 +107,15 @@ struct modConfData_s {
|
||||
static modConfData_t *loadModConf = NULL; /* modConf ptr for current load process */
|
||||
|
||||
/* module-level parameters (module(...)) */
|
||||
static struct cnfparamdescr modpdescr[] = {{"listenportfilename", eCmdHdlrString, 0}, {"aborttimeout", eCmdHdlrInt, 0}};
|
||||
static struct cnfparamdescr modpdescr[] = {
|
||||
{"listenportfilename", eCmdHdlrString, 0},
|
||||
{"aborttimeout", eCmdHdlrInt, 0},
|
||||
{"mainmsgqueuetimeoutshutdown", eCmdHdlrInt, 0},
|
||||
{"mainmsgqueuetimeoutenqueue", eCmdHdlrInt, 0},
|
||||
{"inputshutdowntimeout", eCmdHdlrInt, 0},
|
||||
{"defaultactionqueuetimeoutshutdown", eCmdHdlrInt, 0},
|
||||
{"defaultactionqueuetimeoutenqueue", eCmdHdlrInt, 0},
|
||||
};
|
||||
static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr};
|
||||
|
||||
/* input-level parameters (input(...)) */
|
||||
@ -524,6 +533,20 @@ finalize_it:
|
||||
RETiRet;
|
||||
}
|
||||
|
||||
/* Parse a non-negative long integer from a command argument string.
|
||||
* Returns 1 on success (val set), 0 on parse error (non-numeric, negative, or overflow).
|
||||
*/
|
||||
static int parsePosLong(const uchar *const s, long *const val) {
|
||||
char *endptr;
|
||||
if (s == NULL || *s == '\0') return 0;
|
||||
errno = 0;
|
||||
*val = strtol((const char *)s, &endptr, 10);
|
||||
if (errno != 0) return 0; /* overflow / underflow */
|
||||
/* accept optional trailing newline/space but nothing else */
|
||||
while (*endptr == ' ' || *endptr == '\r' || *endptr == '\n') ++endptr;
|
||||
return (*endptr == '\0' && *val >= 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Function to handle received messages. This is our core function!
|
||||
* rgerhards, 2009-05-24
|
||||
*/
|
||||
@ -566,6 +589,50 @@ static rsRetVal ATTR_NONNULL() OnMsgReceived(tcps_sess_t *const pSess, uchar *co
|
||||
CHKiRet(awaitHUPComplete(pSess));
|
||||
} else if (!ustrcmp(cmdBuf, UCHAR_CONSTANT("enabledebug"))) {
|
||||
CHKiRet(enableDebug(pSess));
|
||||
} else if (!ustrcmp(cmdBuf, UCHAR_CONSTANT("setmainmsgqueuetimeoutshutdown"))) {
|
||||
long val;
|
||||
if (!parsePosLong(pszMsg, &val)) {
|
||||
CHKiRet(sendResponse(pSess, "ERROR: invalid timeout value\n"));
|
||||
} else if (runConf->pMsgQueue == NULL) {
|
||||
CHKiRet(sendResponse(pSess, "ERROR: main queue not yet initialized\n"));
|
||||
} else {
|
||||
CHKiRet(qqueueSettoQShutdown(runConf->pMsgQueue, val));
|
||||
CHKiRet(sendResponse(pSess, "OK\n"));
|
||||
}
|
||||
} else if (!ustrcmp(cmdBuf, UCHAR_CONSTANT("setmainmsgqueuetimeoutenqueue"))) {
|
||||
long val;
|
||||
if (!parsePosLong(pszMsg, &val)) {
|
||||
CHKiRet(sendResponse(pSess, "ERROR: invalid timeout value\n"));
|
||||
} else if (runConf->pMsgQueue == NULL) {
|
||||
CHKiRet(sendResponse(pSess, "ERROR: main queue not yet initialized\n"));
|
||||
} else {
|
||||
CHKiRet(qqueueSettoEnq(runConf->pMsgQueue, val));
|
||||
CHKiRet(sendResponse(pSess, "OK\n"));
|
||||
}
|
||||
} else if (!ustrcmp(cmdBuf, UCHAR_CONSTANT("setinputshutdowntimeout"))) {
|
||||
long val;
|
||||
if (!parsePosLong(pszMsg, &val)) {
|
||||
CHKiRet(sendResponse(pSess, "ERROR: invalid timeout value\n"));
|
||||
} else {
|
||||
runConf->globals.inputTimeoutShutdown = (int)val;
|
||||
CHKiRet(sendResponse(pSess, "OK\n"));
|
||||
}
|
||||
} else if (!ustrcmp(cmdBuf, UCHAR_CONSTANT("setdefaultactionqueuetimeoutshutdown"))) {
|
||||
long val;
|
||||
if (!parsePosLong(pszMsg, &val)) {
|
||||
CHKiRet(sendResponse(pSess, "ERROR: invalid timeout value\n"));
|
||||
} else {
|
||||
runConf->globals.actq_dflt_toQShutdown = (int)val;
|
||||
CHKiRet(sendResponse(pSess, "OK\n"));
|
||||
}
|
||||
} else if (!ustrcmp(cmdBuf, UCHAR_CONSTANT("setdefaultactionqueuetimeoutenqueue"))) {
|
||||
long val;
|
||||
if (!parsePosLong(pszMsg, &val)) {
|
||||
CHKiRet(sendResponse(pSess, "ERROR: invalid timeout value\n"));
|
||||
} else {
|
||||
runConf->globals.actq_dflt_toEnq = (int)val;
|
||||
CHKiRet(sendResponse(pSess, "OK\n"));
|
||||
}
|
||||
} else {
|
||||
dbgprintf("imdiag unkown command '%s'\n", cmdBuf);
|
||||
CHKiRet(sendResponse(pSess, "unkown command '%s'\n", cmdBuf));
|
||||
@ -760,8 +827,19 @@ BEGINsetModCnf
|
||||
CHKmalloc(loadModConf->pszLstnPortFileName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL));
|
||||
} else if (!strcmp(modpblk.descr[i].name, "aborttimeout")) {
|
||||
loadModConf->abortTimeout = (int)pvals[i].val.d.n;
|
||||
} else if (!strcmp(modpblk.descr[i].name, "mainmsgqueuetimeoutshutdown")) {
|
||||
loadModConf->pConf->globals.mainQ.iMainMsgQtoQShutdown = (int)pvals[i].val.d.n;
|
||||
} else if (!strcmp(modpblk.descr[i].name, "mainmsgqueuetimeoutenqueue")) {
|
||||
loadModConf->pConf->globals.mainQ.iMainMsgQtoEnq = (int)pvals[i].val.d.n;
|
||||
} else if (!strcmp(modpblk.descr[i].name, "inputshutdowntimeout")) {
|
||||
loadModConf->pConf->globals.inputTimeoutShutdown = (int)pvals[i].val.d.n;
|
||||
} else if (!strcmp(modpblk.descr[i].name, "defaultactionqueuetimeoutshutdown")) {
|
||||
loadModConf->pConf->globals.actq_dflt_toQShutdown = (int)pvals[i].val.d.n;
|
||||
} else if (!strcmp(modpblk.descr[i].name, "defaultactionqueuetimeoutenqueue")) {
|
||||
loadModConf->pConf->globals.actq_dflt_toEnq = (int)pvals[i].val.d.n;
|
||||
} else {
|
||||
dbgprintf("imdiag: program error, non-handled param '%s' in setModCnf\n", modpblk.descr[i].name);
|
||||
assert(0); /* should not happen */
|
||||
}
|
||||
}
|
||||
loadModConf->configSetViaV2Method = 1;
|
||||
@ -822,6 +900,7 @@ BEGINnewInpInst
|
||||
CHKmalloc(port = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL));
|
||||
} else {
|
||||
dbgprintf("imdiag: program error, non-handled param '%s' in newInpInst\n", inppblk.descr[i].name);
|
||||
assert(0); /* should not happen */
|
||||
}
|
||||
}
|
||||
/* apply module-level listenportfilename to global before addTCPListener uses it */
|
||||
@ -912,6 +991,7 @@ BEGINmodExit
|
||||
void *dummy;
|
||||
pthread_join(timeoutGuard_thrd, &dummy);
|
||||
}
|
||||
abortTimeout = -1; /* mark cleaned up so resetConfigVariables won't double-cancel */
|
||||
}
|
||||
ENDmodExit
|
||||
|
||||
|
||||
@ -1866,7 +1866,7 @@ static rsRetVal process_top_level(yaml_parser_t *parser, const char *key, const
|
||||
CHKiRet(parse_singleton_obj(parser, CNFOBJ_GLOBAL, fname));
|
||||
} else if (!strcmp(key, "mainqueue") || !strcmp(key, "main_queue")) {
|
||||
CHKiRet(parse_singleton_obj(parser, CNFOBJ_MAINQ, fname));
|
||||
} else if (!strcmp(key, "modules")) {
|
||||
} else if (!strcmp(key, "modules") || !strcmp(key, "testbench_modules")) {
|
||||
CHKiRet(parse_obj_sequence(parser, CNFOBJ_MODULE, fname));
|
||||
} else if (!strcmp(key, "inputs")) {
|
||||
CHKiRet(parse_obj_sequence(parser, CNFOBJ_INPUT, fname));
|
||||
|
||||
@ -164,13 +164,12 @@ must validate YAML-loader behaviour or when no RainerScript is desired.
|
||||
|
||||
### How it works
|
||||
- `generate_conf --yaml-only [instance]` writes `${TESTCONF_NM}[instance].yaml`
|
||||
containing `version: 2`, `global:`, `mainqueue:`, and `modules:` (imdiag).
|
||||
The `modules:` sequence is intentionally left open — no `inputs:` section is
|
||||
written by the preamble.
|
||||
- Tests append additional module entries as **sequence continuation items**
|
||||
(2-space indent, ` - load: ...`, no top-level `modules:` key) so YAML parsers
|
||||
see a single, well-formed `modules:` list. The sequence closes naturally when
|
||||
the test adds a zero-indent key such as `inputs:`.
|
||||
containing `version: 2`, `global:`, and `testbench_modules:` (imdiag setup).
|
||||
`testbench_modules:` is a YAML key understood by rsyslogd as an alias for
|
||||
`modules:` and is reserved for testbench infrastructure — it avoids any
|
||||
conflict with the test's own `modules:` section.
|
||||
- Tests add their own `modules:` section (and `inputs:`, `rulesets:`, etc.)
|
||||
via `add_yaml_conf`.
|
||||
- `add_yaml_conf 'fragment' [instance]` appends arbitrary YAML to the same file.
|
||||
- `add_yaml_imdiag_input [instance]` appends the imdiag input entry
|
||||
(` - type: imdiag / port: "0"`) inside an already-opened `inputs:` block.
|
||||
@ -184,8 +183,11 @@ The following testbench features are **not available** in yaml-only mode:
|
||||
|
||||
| Feature | Reason | Workaround |
|
||||
|---------|--------|-----------|
|
||||
| `$MainmsgQueueTimeout*` directives | Legacy sysklogd syntax; no YAML equivalent at runtime via `add_yaml_conf` | Set `RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT` / `RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE` env vars *before* calling `generate_conf --yaml-only`; they are written into the `mainqueue:` section of the preamble |
|
||||
| `.started` marker file | The syslogtag-based filter rule requires RainerScript/legacy syntax | `wait_startup` requires the imdiag port file (not just the PID file) in yaml-only mode, confirming config loaded and inputs are active; it fast-fails if rsyslog exits before the port file appears |
|
||||
| Legacy `$` directives | Legacy syntax is not parsed by the YAML loader | Use v2 RainerScript (`module()`, `input()`) or YAML keys instead |
|
||||
|
||||
> **Note**: Startup detection uses the imdiag port file in both RainerScript and
|
||||
> yaml-only modes. The `.started` marker file mechanism has been removed; the
|
||||
> imdiag port file is the sole startup signal in all modes.
|
||||
|
||||
### Example test structure
|
||||
```bash
|
||||
@ -194,7 +196,8 @@ require_plugin imtcp
|
||||
export NUMMESSAGES=100
|
||||
export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
|
||||
generate_conf --yaml-only
|
||||
# Continue the modules: sequence opened by the preamble (2-space indent, no modules: key)
|
||||
# Test-specific modules in their own modules: section (testbench_modules: is in preamble)
|
||||
add_yaml_conf 'modules:'
|
||||
add_yaml_conf ' - load: "../plugins/imtcp/.libs/imtcp"'
|
||||
add_yaml_conf ''
|
||||
add_yaml_conf 'inputs:'
|
||||
|
||||
129
tests/diag.sh
129
tests/diag.sh
@ -285,6 +285,10 @@ test_status() {
|
||||
|
||||
setvar_RS_HOSTNAME() {
|
||||
printf '### Obtaining HOSTNAME (prerequisite, not actual test) ###\n'
|
||||
# This helper uses legacy RainerScript $template syntax to capture the
|
||||
# hostname; always run it in RS mode regardless of RSYSLOG_YAML_ONLY.
|
||||
local _saved_yaml_only="${RSYSLOG_YAML_ONLY}"
|
||||
export RSYSLOG_YAML_ONLY=0
|
||||
generate_conf ""
|
||||
add_conf 'module(load="../plugins/imtcp/.libs/imtcp")
|
||||
input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
|
||||
@ -300,6 +304,7 @@ local0.* ./'${RSYSLOG_DYNNAME}'.HOSTNAME;hostname
|
||||
export RS_HOSTNAME="$(cat ${RSYSLOG_DYNNAME}.HOSTNAME)"
|
||||
rm -f "${RSYSLOG_DYNNAME}.HOSTNAME"
|
||||
echo HOSTNAME is: $RS_HOSTNAME
|
||||
export RSYSLOG_YAML_ONLY="${_saved_yaml_only}"
|
||||
}
|
||||
|
||||
|
||||
@ -308,34 +313,26 @@ local0.* ./'${RSYSLOG_DYNNAME}'.HOSTNAME;hostname
|
||||
# finished under stress otherwise
|
||||
# $1 is the instance id, if given (or --yaml-only as first arg; see below)
|
||||
#
|
||||
# YAML-ONLY MODE LIMITATION: In --yaml-only mode, $MainmsgQueueTimeoutEnqueue and
|
||||
# $MainmsgQueueTimeoutShutdown (legacy global directives) cannot be set because the
|
||||
# YAML format does not support sysklogd-style directives. Instead, mainqueue timeout
|
||||
# settings are expressed via the mainqueue: section. Tests requiring custom timeout
|
||||
# values should set RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT / RSTB_ACTION_DEFAULT_Q_TO_SHUTDOWN
|
||||
# / RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE env vars before calling generate_conf --yaml-only.
|
||||
# Queue timeout settings ($MainmsgQueueTimeoutEnqueue, $MainmsgQueueTimeoutShutdown,
|
||||
# inputs.timeout.shutdown and default.action.queue.*) are configured via imdiag
|
||||
# module parameters in the config preamble (module(load="imdiag" ...)). This avoids
|
||||
# post-startup diagtalker round-trips and works identically for RainerScript and
|
||||
# YAML-only modes. Tests that need a non-default value must set the relevant
|
||||
# RSTB_* variable before calling generate_conf.
|
||||
#
|
||||
# Also, the .started marker file is not written in yaml-only mode because the
|
||||
# syslogtag-based filter requires legacy/RainerScript syntax. Startup detection relies
|
||||
# on the imdiag port file and the rsyslogd PID file instead.
|
||||
# Startup detection relies on the imdiag port file in both RainerScript and
|
||||
# yaml-only modes; no .started marker file is used.
|
||||
generate_conf() {
|
||||
local yaml_only=0
|
||||
if [ "$1" = "--yaml-only" ]; then
|
||||
yaml_only=1
|
||||
shift
|
||||
fi
|
||||
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="30000"
|
||||
fi
|
||||
: "${RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT:=10000}"
|
||||
: "${RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT:=60000}"
|
||||
: "${RSTB_ACTION_DEFAULT_Q_TO_SHUTDOWN:=20000}"
|
||||
: "${RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE:=30000}"
|
||||
: "${RSTB_MAIN_Q_TO_ENQUEUE:=30000}"
|
||||
export TCPFLOOD_PORT="$(get_free_port)"
|
||||
if [ "$1" == "" ]; then
|
||||
export TESTCONF_NM="${RSYSLOG_DYNNAME}_" # this basename is also used by instance 2!
|
||||
@ -358,43 +355,38 @@ generate_conf() {
|
||||
fi
|
||||
{
|
||||
printf 'version: 2\n\nglobal:\n'
|
||||
printf ' inputs.timeout.shutdown: "%s"\n' "$RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT"
|
||||
printf ' default.action.queue.timeoutshutdown: "%s"\n' "$RSTB_ACTION_DEFAULT_Q_TO_SHUTDOWN"
|
||||
printf ' default.action.queue.timeoutEnqueue: "%s"\n' "$RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE"
|
||||
printf ' debug.abortOnProgramError: "on"\n'
|
||||
[ -n "$ipproto_line" ] && printf '%s\n' "$ipproto_line"
|
||||
printf '\nmainqueue:\n'
|
||||
printf ' timeoutenqueue: "%s"\n' "$RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE"
|
||||
printf ' timeoutshutdown: "%s"\n' "$RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT"
|
||||
printf '\nmodules:\n'
|
||||
printf '\ntestbench_modules:\n'
|
||||
printf ' - load: "../plugins/imdiag/.libs/imdiag"\n'
|
||||
printf ' listenportfilename: "%s.imdiag%s.port"\n' "$RSYSLOG_DYNNAME" "$1"
|
||||
printf ' aborttimeout: "%s"\n' "$TB_TEST_MAX_RUNTIME"
|
||||
# The modules: sequence is intentionally left open here.
|
||||
# Tests append additional ' - load: ...' items (2-space indent, no modules: key)
|
||||
# which YAML parsers treat as a continuation of this sequence.
|
||||
# The sequence closes when the test adds a zero-indent key (inputs:, rulesets:, etc.).
|
||||
# Tests MUST include the imdiag input in their inputs: section; use the
|
||||
# add_yaml_imdiag_input helper to avoid boilerplate.
|
||||
printf '\n###### append test modules as continuation items ( - load: ...)\n'
|
||||
printf '###### then add inputs: (include imdiag via add_yaml_imdiag_input)\n'
|
||||
printf ' mainmsgqueuetimeoutshutdown: "%s"\n' "$RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT"
|
||||
printf ' mainmsgqueuetimeoutenqueue: "%s"\n' "$RSTB_MAIN_Q_TO_ENQUEUE"
|
||||
printf ' inputshutdowntimeout: "%s"\n' "$RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT"
|
||||
printf ' defaultactionqueuetimeoutshutdown: "%s"\n' "$RSTB_ACTION_DEFAULT_Q_TO_SHUTDOWN"
|
||||
printf ' defaultactionqueuetimeoutenqueue: "%s"\n' "$RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE"
|
||||
printf '\n###### add modules:, inputs:, rulesets: etc. below\n'
|
||||
printf '###### include imdiag input via add_yaml_imdiag_input\n'
|
||||
printf '###### end of testbench instrumentation part, test conf follows:\n'
|
||||
} > ${TESTCONF_NM}$1.yaml
|
||||
else
|
||||
export RSYSLOG_YAML_ONLY=0
|
||||
export TESTCONF_EXT="conf"
|
||||
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'"
|
||||
debug.abortOnProgramError="on")
|
||||
# use legacy-style for the following settings so that we can override if needed
|
||||
$MainmsgQueueTimeoutEnqueue '$RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE'
|
||||
$MainmsgQueueTimeoutShutdown '$RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT'
|
||||
echo 'module(load="../plugins/imdiag/.libs/imdiag"
|
||||
mainmsgqueuetimeoutshutdown="'$RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT'"
|
||||
mainmsgqueuetimeoutenqueue="'$RSTB_MAIN_Q_TO_ENQUEUE'"
|
||||
inputshutdowntimeout="'$RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT'"
|
||||
defaultactionqueuetimeoutshutdown="'$RSTB_ACTION_DEFAULT_Q_TO_SHUTDOWN'"
|
||||
defaultactionqueuetimeoutenqueue="'$RSTB_ACTION_DEFAULT_Q_TO_ENQUEUE'")
|
||||
global(debug.abortOnProgramError="on")
|
||||
$IMDiagListenPortFileName '$RSYSLOG_DYNNAME.imdiag$1.port'
|
||||
$IMDiagServerRun 0
|
||||
$IMDiagAbortTimeout '$TB_TEST_MAX_RUNTIME'
|
||||
|
||||
# Capture rsyslogd own messages (startup, shutdown, errors) to the .started
|
||||
# file. Tests use this file to check for expected rsyslogd-internal messages.
|
||||
# This rule also ensures at least one output action exists in the default
|
||||
# ruleset, which is required by rsyslogd even when only inputs are configured.
|
||||
:syslogtag, contains, "rsyslogd" ./'${RSYSLOG_DYNNAME}$1'.started
|
||||
###### end of testbench instrumentation part, test conf follows:' > ${TESTCONF_NM}$1.conf
|
||||
# Optionally enforce IPv4 for this test instance.
|
||||
@ -941,47 +933,38 @@ check_rsyslog_active() {
|
||||
}
|
||||
|
||||
# wait for rsyslogd startup ($1 is the instance)
|
||||
# Startup is signalled by the imdiag port file appearing (written only after
|
||||
# the imdiag input is fully active). This works for both RainerScript and
|
||||
# yaml-only modes. Fast-fail if the process exits before the port file appears.
|
||||
wait_startup() {
|
||||
local instance=$1
|
||||
local pid_file="$RSYSLOG_PIDBASE$instance.pid"
|
||||
local started_file="${RSYSLOG_DYNNAME}$instance.started"
|
||||
local imdiag_port_file="$RSYSLOG_DYNNAME.imdiag$instance.port"
|
||||
# In yaml-only mode the .started marker is never written (the syslogtag filter
|
||||
# requires RainerScript/legacy syntax). The PID file alone is insufficient because
|
||||
# rsyslogd writes it before activating inputs, so a YAML config error would appear
|
||||
# as a successful startup. Require the imdiag port file (written only after the
|
||||
# input is fully active) instead, and fast-fail if the process exits before that.
|
||||
local _imdiag_port_ready
|
||||
while :; do
|
||||
_imdiag_port_ready=0
|
||||
[ -s "$imdiag_port_file" ] && _imdiag_port_ready=1
|
||||
if [ "$RSYSLOG_YAML_ONLY" = "1" ]; then
|
||||
# yaml-only: imdiag port file is the definitive startup signal
|
||||
[ "$_imdiag_port_ready" = "1" ] && break
|
||||
# fast-fail: process wrote PID file but is already gone (config error)
|
||||
if [ -s "$imdiag_port_file" ]; then
|
||||
# port file seen — quick liveness check before trusting it
|
||||
if [ -s "$pid_file" ] && ! ps -p "$(cat "$pid_file" 2>/dev/null)" > /dev/null 2>&1; then
|
||||
printf '%s ABORT! rsyslog exited during yaml-only startup (config error?)\n' "$(tb_timestamp)"
|
||||
printf '%s ABORT! rsyslog exited immediately after writing port file\n' "$(tb_timestamp)"
|
||||
error_exit 1 stacktrace
|
||||
fi
|
||||
else
|
||||
{ [ -f "$pid_file" ] || [ -f "$started_file" ] || [ "$_imdiag_port_ready" = "1" ]; } \
|
||||
&& break
|
||||
break
|
||||
fi
|
||||
# If we are exactly at/over timeout threshold, re-check once more before aborting
|
||||
# fast-fail: PID written but process already gone (config error)
|
||||
if [ -s "$pid_file" ] && ! ps -p "$(cat "$pid_file" 2>/dev/null)" > /dev/null 2>&1; then
|
||||
printf '%s ABORT! rsyslog exited during startup (config error?)\n' "$(tb_timestamp)"
|
||||
error_exit 1 stacktrace
|
||||
fi
|
||||
# timeout check
|
||||
if [ $(date +%s) -gt $(( TB_STARTTEST + TB_STARTUP_MAX_RUNTIME )) ]; then
|
||||
[ -s "$imdiag_port_file" ] && break
|
||||
if [ "$RSYSLOG_YAML_ONLY" != "1" ]; then
|
||||
{ [ -f "$pid_file" ] || [ -f "$started_file" ]; } && break
|
||||
fi
|
||||
printf '%s ABORT! Timeout waiting startup indicator (%s or %s or %s) after %d seconds\n' "$(tb_timestamp)" "$pid_file" "$started_file" "$imdiag_port_file" $TB_STARTUP_MAX_RUNTIME
|
||||
# show current file states for diagnostics
|
||||
ls -l "$pid_file" "$started_file" "$imdiag_port_file" 2>/dev/null || true
|
||||
# observed late creation on some CI runners; proceed softly and let subsequent waits validate
|
||||
break
|
||||
printf '%s ABORT! Timeout waiting for imdiag port file (%s) after %d seconds\n' \
|
||||
"$(tb_timestamp)" "$imdiag_port_file" $TB_STARTUP_MAX_RUNTIME
|
||||
ls -l "$pid_file" "$imdiag_port_file" 2>/dev/null || true
|
||||
error_exit 1 stacktrace
|
||||
fi
|
||||
$TESTTOOL_DIR/msleep 50 # wait 50 milliseconds
|
||||
done
|
||||
# If we have a pid file, perform a quick liveness check
|
||||
# quick liveness check
|
||||
if [ -f "$pid_file" ]; then
|
||||
$TESTTOOL_DIR/msleep 50
|
||||
check_rsyslog_active $instance
|
||||
@ -2320,7 +2303,7 @@ exit_test() {
|
||||
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 ${TESTCONF_NM}.conf ${TESTCONF_NM}.yaml
|
||||
rm -f tmp.qi nocert
|
||||
rm -fr $RSYSLOG_DYNNAME* # delete all of our dynamic files
|
||||
unset TCPFLOOD_EXTRA_OPTS
|
||||
|
||||
@ -1,18 +1,13 @@
|
||||
#!/bin/bash
|
||||
# Tests that the YAML-only testbench mode works end-to-end:
|
||||
# - generate_conf --yaml-only writes a pure YAML preamble (no RainerScript)
|
||||
# - additional modules are appended as sequence continuations (no duplicate
|
||||
# modules: key) so YAML parsers see a single well-formed modules: list
|
||||
# - generate_conf --yaml-only writes a pure YAML preamble using
|
||||
# testbench_modules: for the imdiag setup (no RainerScript)
|
||||
# - test-specific modules go in a standard modules: section
|
||||
# - add_yaml_imdiag_input adds the imdiag input for startup detection
|
||||
# - rsyslogd starts and processes messages using only the YAML loader
|
||||
#
|
||||
# This test intentionally avoids any RainerScript or legacy-style directives
|
||||
# so that it exercises the yaml-only testbench path introduced alongside the
|
||||
# YAML configuration support.
|
||||
#
|
||||
# Note: queue timeout settings are expressed via mainqueue: in the YAML
|
||||
# preamble (generated by generate_conf --yaml-only) because the legacy
|
||||
# $MainmsgQueueTimeout* directives are not available in yaml-only mode.
|
||||
# so that it exercises the yaml-only testbench path.
|
||||
#
|
||||
# Added 2025 by contributors, released under ASL 2.0
|
||||
. ${srcdir:=.}/diag.sh init
|
||||
@ -20,8 +15,9 @@ require_plugin imtcp
|
||||
export NUMMESSAGES=100
|
||||
export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines
|
||||
generate_conf --yaml-only
|
||||
# Append imtcp as a continuation item of the modules: sequence already opened
|
||||
# by the preamble (2-space indent, no top-level modules: key).
|
||||
# Test-specific modules go in a standard modules: section.
|
||||
# Testbench infrastructure (imdiag) is in testbench_modules: written by the preamble.
|
||||
add_yaml_conf 'modules:'
|
||||
add_yaml_conf ' - load: "../plugins/imtcp/.libs/imtcp"'
|
||||
add_yaml_conf ''
|
||||
add_yaml_conf 'templates:'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user