tests: add libbabeltrace2 pre/postcondition testing infrastructure
This patch adds a basic libbabeltrace2 pre/postcondition testing
infrastructure to the project.
When a libbabeltrace2 public function precondition or postcondition is
not satisfied, the function logs a FATAL-level message which indicates
what's wrong and then aborts. Slow path functions check such conditions
unconditionally, while fast path functions check them only in developer
mode.
Testing that a libbabeltrace2 function catches an unsatisfied
pre/postcondition and reports it is not straightforward: the library
aborts the program, so we can't use the usual approach because the test
program itself would abort.
The solution brought by this patch is the following process in
`tests/lib/conds`:
1. The `conds-triggers.c` program contains all the pre/postcondition
failure triggering instructions to test, one condition per function.
Each triggering function triggers a single pre/postcondition check.
It is expected that the function actually aborts.
main() calls ppc_main(), an internal utility, with its command-line
arguments and an array of condition trigger descriptors.
Each condition trigger descriptor has:
* A condition type: precondition or postcondition.
* The ID of the condition to trigger.
* A name suffix.
* A condition triggering function.
Each condition trigger descriptor has a unique name: its condition ID
and an optional name suffix.
As of this patch, the PPC_TRIGGER_*_RUN_IN_COMP_CLS_INIT() macros
create condition trigger descriptors of which the function runs
within a component class initialization function (accepts a
`bt_self_component *` parameter). This is often needed as many
libbabeltrace2 functions are only accessible through a self component
(all the trace IR API, for example).
ppc_main() handles two command-line subcommands:
`list`:
Prints a JSON array of objects which represent the triggering
descriptors, for example (output for this patch):
[
{
"cond-id": "pre:field-class-integer-set-field-value-range:valid-n",
"name": "pre:field-class-integer-set-field-value-range:valid-n-0"
},
{
"cond-id": "pre:field-class-integer-set-field-value-range:valid-n",
"name": "pre:field-class-integer-set-field-value-range:valid-n-gt-64"
},
{
"cond-id": "pre:field-class-integer-set-field-value-range:not-null:field-class",
"name": "pre:field-class-integer-set-field-value-range:not-null:field-class"
}
]
`run INDEX`:
Runs the condition triggering function for the descriptor at
index `INDEX` in the `list` array.
It is expected that this command aborts.
2. `test_conds` is a Bash script which only does this:
reldir=lib/conds
export BT_TESTS_LIB_CONDS_TRIGGER_BIN="$BT_TESTS_BUILDDIR/$reldir/conds-triggers"
if [ "$BT_OS_TYPE" = "mingw" ]; then
BT_TESTS_LIB_CONDS_TRIGGER_BIN="$BT_TESTS_LIB_CONDS_TRIGGER_BIN.exe"
fi
run_python_bt2_test "$BT_TESTS_SRCDIR/$reldir" test.py
In other words, it runs the Python TAP test runner to discover and
run tests in `test.py`.
This script is part of the `make check` test set.
3. In `test.py`, a function:
a) Runs `conds-triggers list` and decodes the output to get the list
of available condition trigger descriptors.
This step also validates the regular expressions and checks that
there are no duplicate descriptor names.
b) For each condition trigger descriptor, creates and adds a test to
its single test case class which:
I. Executes `conds-triggers run INDEX` as a subprocess,
where `INDEX` is the descriptor's index.
II. Reads the complete process's standard error.
III. Asserts that the process aborts (`SIGABRT` signal).
This seems to be only possible on a POSIX system with the
`subprocess.Popen` API.
IV. Asserts that the standard error (II) contains the
descriptor's condition ID.
All this is only enabled if, at configuration time:
* Python 3 is available.
* The Babeltrace 2 developer mode is enabled (`BABELTRACE_DEV_MODE=1`).
This patch's `conds-triggers.c` includes two precondition triggering
functions to confirm that everything works as expected:
trigger_fc_int_set_field_value_range_n_0():
When calling bt_field_class_integer_set_field_value_range(), the
parameter `N` cannot be greater than 64.
trigger_fc_int_set_field_value_range_n_gt_64():
When calling bt_field_class_integer_set_field_value_range(), the
parameter `N` cannot be 0.
trigger_fc_int_set_field_value_range_null():
When calling bt_field_class_integer_set_field_value_range(), the
field class cannot be `NULL`.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I70713d690f7dbfeac5804e6cfcec989242823611
Reviewed-on: https://review.lttng.org/c/babeltrace/+/3401
This page took 0.030385 seconds and 4 git commands to generate.