From 7dd06a04f1135e6b463c7a8596b0c055fbf1aaaf Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Tue, 22 Oct 2019 17:55:25 -0400 Subject: [PATCH] tests: add CLI query tests Add a few simple tests for the query CLI command, using a custom Python component class. Change-Id: Ic2b2d3f9f5e0f460f596bd1e4403c250ec2daad5 Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/2245 Tested-by: jenkins Reviewed-by: Philippe Proulx --- tests/Makefile.am | 2 + tests/cli/query/test_query | 98 ++++++++++++++++++++++ tests/data/cli/params/bt_plugin_params.py | 32 +------ tests/data/cli/query/bt_plugin_query.py | 35 ++++++++ tests/utils/python/cli_params_to_string.py | 50 +++++++++++ 5 files changed, 186 insertions(+), 31 deletions(-) create mode 100755 tests/cli/query/test_query create mode 100644 tests/data/cli/query/bt_plugin_query.py create mode 100644 tests/utils/python/cli_params_to_string.py diff --git a/tests/Makefile.am b/tests/Makefile.am index 079e7922..d341c3cd 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -42,6 +42,7 @@ dist_check_SCRIPTS = \ cli/convert/test_auto_source_discovery_log_level \ cli/convert/test_convert_args \ cli/params/test_params \ + cli/query/test_query \ cli/test_exit_status \ cli/test_help \ cli/test_intersection \ @@ -126,6 +127,7 @@ TESTS_CLI += \ cli/convert/test_auto_source_discovery_log_level \ cli/convert/test_auto_source_discovery_params \ cli/params/test_params \ + cli/query/test_query cli/test_exit_status TESTS_PLUGINS += plugins/flt.utils.trimmer/test_trimming \ diff --git a/tests/cli/query/test_query b/tests/cli/query/test_query new file mode 100755 index 00000000..1be9fa24 --- /dev/null +++ b/tests/cli/query/test_query @@ -0,0 +1,98 @@ +#!/bin/bash +# +# Copyright (C) 2019 Simon Marchi +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# This program 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 +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +if [ "x${BT_TESTS_SRCDIR:-}" != "x" ]; then + UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh" +else + UTILSSH="$(dirname "$0")/../../utils/utils.sh" +fi + +# shellcheck source=../../utils/utils.sh +SH_TAP=1 source "$UTILSSH" + +NUM_TESTS=11 + +plan_tests $NUM_TESTS + +data_dir="${BT_TESTS_DATADIR}/cli/query" +plugin_dir="${data_dir}" + +stdout_expected_file=$(mktemp -t test_cli_query_stdout_xpected.XXXXXX) +stdout_file=$(mktemp -t test_cli_query_stdout.XXXXXX) +stderr_file=$(mktemp -t test_cli_query_stderr.XXXXXX) + +expect_success() { + local expected_str="$1" + shift 1 + local args=("$@") + + echo "$expected_str" > "$stdout_expected_file" + + bt_diff_cli "$stdout_expected_file" /dev/null \ + --plugin-path "$plugin_dir" \ + query "src.query.SourceWithQueryThatPrintsParams" \ + "${args[@]}" + ok "$?" "${args[*]}" +} + +expect_failure() { + local expected_str="$1" + shift 1 + local args=("$@") + local test_name="${args[*]}" + + echo -n > "$stdout_expected_file" + + bt_cli "$stdout_file" "$stderr_file" \ + --plugin-path "$plugin_dir" \ + query \ + "${args[@]}" + isnt "$?" 0 "${test_name}: exit code is not 0" + + bt_diff /dev/null "$stdout_file" + ok "$?" "${test_name}: nothing output on stout" + + # Ensure that a CLI error stack is printed (and that babeltrace doesn't + # abort before that). + grep --silent "^ERROR: " "${stderr_file}" + ok $? "${test_name}: babeltrace produces an error stack" + + grep --silent "${expected_str}" "${stderr_file}" + ok "$?" "${test_name}: expect \`${expected_str}\` error message on stderr" +} + +expect_success 'the-object:{}' \ + 'the-object' +expect_success "the-object:{a=2}" \ + 'the-object' -p 'a=2' + +# Check that -p parameters are processed in order. +expect_success "the-object:{a=3, ben=kin, voyons=donc}" \ + 'the-object' -p 'a=2,ben=kin' -p 'voyons=donc,a=3' + +# Failure inside the component class' query method. +expect_failure "ValueError: catastrophic failure" \ + 'src.query.SourceWithQueryThatPrintsParams' 'please-fail' '-p' 'a=2' + +# Non-existent component class. +expect_failure 'Cannot find component class: plugin-name="query", comp-cls-name="NonExistentSource", comp-cls-type=1' \ + 'src.query.NonExistentSource' 'the-object' '-p' 'a=2' + + +rm -f "$stdout_expected_file" +rm -f "$stdout_file" +rm -f "$stderr_file" diff --git a/tests/data/cli/params/bt_plugin_params.py b/tests/data/cli/params/bt_plugin_params.py index 63c655b0..873dfa84 100644 --- a/tests/data/cli/params/bt_plugin_params.py +++ b/tests/data/cli/params/bt_plugin_params.py @@ -17,37 +17,7 @@ # import bt2 - - -def to_string(p): - # Print BT values in a predictable way (the order of map entries) and with - # additional information (u suffix to differentiate unsigned integers from - # signed integers). - - if type(p) is bt2._ArrayValueConst: - s = '[{}]'.format(', '.join([to_string(x) for x in p])) - elif type(p) is bt2._MapValueConst: - s = '{{{}}}'.format( - ', '.join([k + '=' + to_string(p[k]) for k in sorted(p.keys())]) - ) - elif type(p) is bt2._UnsignedIntegerValueConst: - s = str(p) + 'u' - elif ( - type(p) - in ( - bt2._StringValueConst, - bt2._SignedIntegerValueConst, - bt2._RealValueConst, - bt2._BoolValueConst, - ) - or p is None - ): - s = str(p) - - else: - raise TypeError('Unexpected type', type(p)) - - return s +from cli_params_to_string import to_string @bt2.plugin_component_class diff --git a/tests/data/cli/query/bt_plugin_query.py b/tests/data/cli/query/bt_plugin_query.py new file mode 100644 index 00000000..65dcfa8b --- /dev/null +++ b/tests/data/cli/query/bt_plugin_query.py @@ -0,0 +1,35 @@ +# +# Copyright (C) 2019 EfficiOS Inc. +# +# This program 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; only version 2 +# of the License. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import bt2 +from cli_params_to_string import to_string + + +@bt2.plugin_component_class +class SourceWithQueryThatPrintsParams( + bt2._UserSourceComponent, message_iterator_class=bt2._UserMessageIterator +): + @classmethod + def _user_query(cls, executor, obj, params, method_obj): + if obj == 'please-fail': + raise ValueError('catastrophic failure') + + return obj + ':' + to_string(params) + + +bt2.register_plugin(__name__, "query") diff --git a/tests/utils/python/cli_params_to_string.py b/tests/utils/python/cli_params_to_string.py new file mode 100644 index 00000000..a3d5ff85 --- /dev/null +++ b/tests/utils/python/cli_params_to_string.py @@ -0,0 +1,50 @@ +# +# Copyright (C) 2019 EfficiOS Inc. +# +# This program 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; only version 2 +# of the License. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import bt2 + + +def to_string(p): + # Print BT values in a predictable way (the order of map entries) and with + # additional information (u suffix to differentiate unsigned integers from + # signed integers). + + if type(p) is bt2._ArrayValueConst: + s = '[{}]'.format(', '.join([to_string(x) for x in p])) + elif type(p) is bt2._MapValueConst: + s = '{{{}}}'.format( + ', '.join([k + '=' + to_string(p[k]) for k in sorted(p.keys())]) + ) + elif type(p) is bt2._UnsignedIntegerValueConst: + s = str(p) + 'u' + elif ( + type(p) + in ( + bt2._StringValueConst, + bt2._SignedIntegerValueConst, + bt2._RealValueConst, + bt2._BoolValueConst, + ) + or p is None + ): + s = str(p) + + else: + raise TypeError('Unexpected type', type(p)) + + return s -- 2.34.1